
    *j^                    4$   U d Z ddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddl
Z
ddlmZ ddlmZ ddlmZmZ ddlmZmZmZmZ ddlm Z  ddl!m"Z"m#Z#m$Z$  ej%        e&          Z'e(e)e*e+e,fZ-i Z.e/e0e1f         e2d	<    ej3                    Z4i Z5e/e0e/f         e2d
<    ej3                    Z6dZ7dZ8dZ9d eD             Z:ddi dZ;e/e0e<f         e2d<    ej3                    Z=ddhZ> ej%        d          Z?i Z@e/e0eAe1         f         e2d<    ej3                    ZBdZCdZDdZE ej%        d          ZFi ZGe/e0eAe1         f         e2d<    ej3                    ZHdZIdZJdZKdddddd d!d"ZLdd#ZMdd$lNmOZO d%ePfd&ZQd%efd'ZRd(ed)ed%ePfd*ZSd+ed,eAe         d%e0dz  fd-ZTd.ed%eAe         fd/ZUd%e/fd0ZVd1e0d%e/fd2ZWdd.ed3e0dz  d%e/fd4ZXd5e0d,eAe         d%eYedz  edz  f         fd6ZZd5e0d.ed%eYedz  edz  f         fd7Z[d5e0d.ed%e/fd8Z\d9edz  d%e/fd:Z]d9edz  d+ed%e/fd;Z^d5e0d%e/fd<Z_d=Z`d%e0fd>Zad%ePfd?Zbd@ ZcdA Zdd%e/e0e/f         fdBZedCe0fdDZfdCe0fdEZgdCe0d%eYePe1f         fdFZhdGe0d%eifdHZje8fdGe0dIeid%e0fdJZkdKe/d%e/fdLZld%eAe/         fdMZmd%ene0         fdNZod%e0dz  fdOZpdKe/fdPZqdQ ZrdR ZsdS ZtddTZudUdVdWdVdXZvdYdZd[d\d]d^d_d`ZwdaZxi Zye/eYe0e0f         eYe1e/f         f         e2db<    ejz                    Z{d%e0fdcZ|dde0d%eYe0e0f         fdeZ}dfeYe0e0f         d%e/dz  fdgZ~dfeYe0e0f         dhe/d%dfdiZddjZddklmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddllmZmZmZmZmZmZmZmZmZmZ ddmlmZ ddnlmZ ddolmZ dpe0d%ePfdqZd%ePfdrZdsdtdue/dvePd%e/fdwZd1e0fdxZd%ePfdyZddl
Zdze0d%eYe0e0dz  f         fd{Zd|e0d}e0dz  d~e0dz  d%ePfdZd%ene0         fdZd%ePfdZde0d%ePfdZdZde0d%ePfdZǐddZd%e0fdZd%ePfdZd%e0fdZddde1dz  d%ePfdZddde1dz  d%ePfdZ͐ddeid%ePfdZd Zd%ePfdZdIeid%e0dz  fdZd%e0dz  fdZdhe/dz  d%e/fdZd%e/fdZde/d%ePfdZdze0dz  d%e0fdZde/d%eYene0         ene0         f         fdZde0de0dene0         dene0         d%ePf
dZde0de0d%ePfdZd)e0de0d%ePfdZdze0dz  d%e0dz  fdZde0d%eYe0e0dz  f         fdZde0de0de/d%ePfdZ	 dde0dz  de0dz  d%eYe0e0dz  ePf         fdZde0dz  d%eYe0ePf         fdZd%e0fdZd%e0fdZd%e0dz  fdZ	 dde0dz  dde0dz  d%eifdZ	 dde0dz  de0dz  de0dz  d%eYe0dz  e0dz  f         fdZde0d%e/fdZde0d%e/fdZde/de0d%e0fdZde/d%e0fdZde/d%ePfdZd%eifdZde/dene0         dene0         d%ePfdZd%ePfdZd%ePfdZdeideid%eAfdńZd%ePfdƄZdd%eYeAeif         fdǄZdd%eAfdȄZd%e/fdɄZdd1e0de0dz  d%e/fd˄Zd%ePfd̄Zd1e0d%ePfd̈́Zde/d%e1fd΄Zde/d%ePfdτZdZefdeAe/         deid%eAe/         fdӄZde/de/d%e/fdքZde/d%e0dz  fdׄZdsd؜deAe/         dePd%eAe/         fdڄZddlmZmZm Z mZmZmZmZmZmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ ddܐlmZmZmZmZmZmZmZmZmZmZmZmZmZm Z  ddݐl!m"Z"m#Z#m$Z$ ddސl%m&Z&m'Z'm(Z(m)Z) ddߐl*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z< 	 ddl=m>Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZK nQ# eL$ rH d Z?d Z@d ZAd ZBd ZCd ZHd ZId ZJd ZKi ZD ej3                    ZE en            ZFi ZGY nw xY wi ZMe/e0eAe	jN                 f         e2d<   de0d%e	jN        fdZOde0de	jN        d%dfdZPde0de/dz  deid%dfdZQde0de/dz  deid%dfdZRde0de/d%dfdZ>	 ddlSm>ZTmUZVmWZWmXZXmYZZm[Z\ n# eL$ r d ZTd ZVdZZd ZWd ZXY nw xY wdddd ddddddddddd	dd
ddddddddddddddddddddddddddd dd!d"dd#dd$d%dd&d'dd(d)d*d d)d+d,dd-d.d/d0d.d1d2dd3dd4d5dd6d7dd8d9d:d;d9d<d=dd>d?d@dAd?dBdCddDZ]dEe0dz  d%e0fdFZ^dGZ_dHdIdJdKZ`h dLZadZbdMZcd%eifdNZdd%ePfdOZedPZfdQZgd%efdRZhdSed%e0dz  fdTZidUe/dVe0d%e0dz  fdWZjd%e0dz  fdXZkdYZl emdZ d[D                       Znd%eYee0ePf         fd\Zod]e1dz  d%e0dz  fd^Zpd_ed%eifd`Zqdaed%eAe         fdbZrd%e/fdcZsd%ePfddZtd%ePfdeZud%e/fdfZvddhe1d%e/fdiZwd%e/fdjZxd%e/fdkZyddle/dz  d%eYe/ePf         fdmZzdn Z{doZ| ene|          Z}dp Z~dqdrd%e0fdsZdd%e/fdtZd%ePfduZdvZdwed%ePfdxZd%ePfdyZd%ePfdzZd%ePfd{Zd%ePfd|Zd%ePfd}Zd%ePfd~Zd%ePfdZdddddddddddddZh dZh dZi Ze/e2d<    ej3                    Zd Zd Zd ZddZd Zd ZddZde/d%eidz  fdZde0deidz  d%ePfdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zde0de0d%e0fdZde0deid%eYeieif         dz  fdZdddede0de0de0de0dz  f
dZded%efdZdede0de0fdZd Zd1e0de0d%edz  fdZd%eifdZd%eifdZdededeideifdZd Zd Zd Zd Zd ZdÄ ZdĄ Zdń ZdƄ ZdǄ ZdȄ ZdɄ ZdGe0d%e/fdʄZddGe0dIeid%e0fd˄Zd̄ Zd̈́ Zd΄ Zdτ ZddЄZdф Zd҄ ZÐde0de1dz  d%dfdՄZd%ePfdքZŐdde0de0d%e0fdڄZddۜde0de0de0de0de1dz  f
d݄Zd%ePfdބZdddsddsdߜde0de0de0dePdePf
dZɐd Zʐd Zːde0d%e0fdZ̐d Z͐ddZd%e0fdZϐd ZАd Zѐd ZҐd ZӐd ZԐd ZՐd Z֐d Zאd Zde0fdZde0fdZde0fdZd%ePfdZd%ePfdZݐd Zސd Zߐd ZddeifdZd%eAe0         fdZd Zd Zd  Zdde0de0d%e0fdZd Zd Zd Zd Zde0fd	Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd1e0de0de0d%ePfdZd Zd1e0de0de0d%ePfdZd Z G d  d!          Zdd"Zd# Z d$ Zd% Zd& Zd' Zd( Z	 	 dd1e0due0d)e0dz  d*eidz  dePd%e/fd+Zd,e/d%e/dz  fd-Zd.e/de/d%ePfd/Zd0e<d1e/dz  d%ePfd2Z	d1e0d,e/d%ePfd3Z
d1e0d,e/d%ePfd4Zdd1e0due0d)e0dz  d*eidz  dePd%e/fd5Zd6 Zd7 Zd8 Zd%eAe0         fd9Zd5e0d:ePd%eAe0         fd;Zd< Zd= Zd,e<d%e<fd>Zd,e<d%ePfd?Zd,e<d%e<fd@ZdAeAdBeAd%ePfdCZdAeAdBeAd%ePfdDZdE ZdF ZddGlmZmZmZmZ dH Zd%ePfdIZd%e/e0e/f         fdJZddKZdIeid%e0fdLZ d%e0fdMZ!dNdrdIeid%eAe/         fdOZ"dP Z#dQ Z$dR Z%dS Z&dT Z'd%ePfdUZ(ddVe/dz  d%ePfdWZ)h dXZ*h dYZ+dZd[d\d]d^d\d_d`d\gdZdad\dbdcd\gddded\dfdgd\gdhdid\djdkd\gdhdid\djdkd\gdlZ,d5e0d%e0fdmZ-dne0doeAe/         d%ePfdpZ.dne0d%eAe/         fdqZ/dre/dseAe/         d%eAe/         fdtZ0du Z1dve0d%e/fdwZ2d%eYe0e0f         fdxZ3dde0dye/dz  d%e/fdzZ4dd|drde0d}e0dIeid%e0fd~Z5dАdrd}e0dIeid%eAe/         fdZ6de0d%e/fdZ7g dZ8d%edz  fdZ9ddedz  d%eAe/         fdZ:ddrdIeid%eAe/         fdZ;d Z<d Z=d Z>d Z?d Z@dZAd ZBd ZCdS (  z
Hermes Web UI -- Route handlers for GET and POST endpoints.
Extracted from server.py (Sprint 11) so server.py is a thin shell.
    NPath)closing)parse_qsurlsplit)MESSAGING_SOURCESis_cli_session_rowis_cli_session_row_visibleread_session_lineage_report)visible_messages_for_anchor)publish_session_list_changedsubscribe_session_eventsunsubscribe_session_events_RUNNING_CRON_JOBS_MANUAL_COMPRESSION_JOBSX  i@     c                 t    h | ]5}t          |                                                                          6S  strstriplower.0ss     -/Users/bertmahoney/hermes-webui/api/routes.py	<setcomp>r   @   s2    LLLQ#a&&,,....00LLL    )pathmtimeidentity!_MESSAGING_SESSION_METADATA_CACHEsession_resetsession_switch
csp_report_CSP_REPORT_RATE_LIMIT<   d   i   client_event_CLIENT_EVENT_RATE_LIMIT   i   @   P                )eventsource
session_id	stream_idvisibility_stateurl_pathreasonc                 z    t          | t                    r|                     ||          S t          | ||          S N
isinstancedictgetgetattr)sessionfielddefaults      r   _session_fieldrD   _   s:    '4   +{{5'***7E7+++r   )_profiles_matchreturnc                     t          | j                  }|                    ddg          d                                                                         }|dv S )zReturn True if the request URL has `?all_profiles=1` (or true/yes).

    Centralizes the opt-in parsing so /api/sessions and /api/projects use
    the same shape. Accepts 1/true/yes (case-insensitive) for ergonomics.
    all_profiles r   )1trueyeson)r   queryr?   r   r   )
parsed_urlqsraws      r   _all_profiles_query_flagrR   y   sR     
*"	#	#B
&&"
&
&q
)
/
/
1
1
7
7
9
9C,,,r   c                  d   	 ddl m}  t           |                       dz  S # t          $ r 	 ddlm} t          |          cY S # t          $ r] t          t          j        dt          t          j	                    dz                                
                                dz  cY cY S w xY ww xY w)a  Return the skills directory for the request's active Hermes profile.

    WebUI profile switches are cookie/thread-local scoped, so the agent
    module-level ``tools.skills_tool.SKILLS_DIR`` can still point at the server
    startup profile. Skills UI endpoints must derive the directory from
    ``get_active_hermes_home()`` for every request instead of reading that
    process-global constant.
    r   get_active_hermes_homeskills)
SKILLS_DIRHERMES_HOME.hermes)api.profilesrU   r   	Exceptiontools.skills_toolrW   osgetenvr   home
expanduser)rU   rW   s     r   _active_skills_dirra      s    
h777777**,,--88 h h h	h444444
##### 	h 	h 	h	-TY[[95L1M1MNNOOZZ\\_ggggggg	hhs-   " 
B/AB/A"B+&B/*B++B/base_dir	candidatec                     	 |                                                     |                                             dS # t          t          f$ r Y dS w xY w)NTF)resolverelative_toOSError
ValueError)rb   rc   s     r   _skill_path_withinri      s_    ''(8(8(:(:;;;tZ    uus   9= AAskill_mdskills_dirsc                     |D ]O}	 |                      |          }n# t          $ r Y %w xY w|j        }t          |          dk    r
|d         c S  d S d S )N   r   )rf   rh   partslen)rj   rk   
skills_dirrel_pathrn   s        r   _skill_category_from_pathrr      sz    !  
	++J77HH 	 	 	H	u::??8OOOtt4s   
))rp   c                     | g}	 ddl m} |                    d  |            D                        n# t          $ r Y nw xY wd |D             S )Nr   )get_external_skills_dirsc              3   4   K   | ]}t          |          V  d S r;   r   r   ps     r   	<genexpr>z,_active_skill_search_dirs.<locals>.<genexpr>   s(      @@DGG@@@@@@r   c                 :    g | ]}|                                 |S r   )existsrv   s     r   
<listcomp>z-_active_skill_search_dirs.<locals>.<listcomp>   s%    ***!qxxzz*A***r   )agent.skill_utilsrt   extendr[   )rp   dirsrt   s      r   _active_skill_search_dirsr      s    <D>>>>>>@@%=%=%?%?@@@@@@@   **t****s   -3 
A A c                     | rt          | dd          nd}|si S d|d}t          | dd          }t          | dd          }|r||d<   |r||d<   |S )zHReturn explicit no-cleanup metadata for worktree-backed session actions.worktree_pathNT)worktree_retainedr   worktree_branchworktree_repo_rootr@   )rA   r   payloadr   r   s        r   _worktree_retained_payloadr      s    ?FPGG_d;;;DM 	!& G g'8$??O *>EE 5%4!" ;(:$%Nr   sidc                     	 t          t          | d                    S # t          $ r i cY S t          $ r  t                              d|            i cY S w xY w)NTmetadata_onlyz7Failed to read worktree metadata for deleted session %s)r   get_sessionKeyErrorr[   loggerdebug)r   s    r   )_worktree_retained_payload_for_session_idr      sw    )+c*N*N*NOOO   			   NPSTTT			s     A&AAcategoryc           
      x   ddl m} ddlm}mm}m}m}m} | 	                                s"| 
                    dd           dg g d|  ddS g }t                      }	 |            }
t          |           }|D ]} ||d	          D ]}t          fd
|j        D                       r$|j        }	 |                    d          dd         } ||          \  }} ||          sd|                    d|j                  dd         }||	v r|                    dd          }|sY|                                                    d          D ]1}|                                }|r|                    d          s|} n2t-          |          |k    r|d|dz
           dz   }|	                    |           |                    ||t3          ||          ||
v d           a# t4          t6          f$ r'}t8                              d||           Y d}~d}~wt<          $ r)}t8                              d||d           Y d}~d}~ww xY wމrfd|D             } ||          }t?          t          d |D                                 }d||t-          |          d}|rd|d<   nd |d!<   |S )"a  List skills using an explicit local skills directory.

    This mirrors ``tools.skills_tool.skills_list`` closely, but keeps the local
    scan root explicit so per-client WebUI profile switches do not race on or
    leak through the skills tool's module-global ``SKILLS_DIR``.
    r   iter_skill_index_files)MAX_DESCRIPTION_LENGTH_EXCLUDED_SKILL_DIRS_get_disabled_skill_names_parse_frontmatter_sort_skillsskill_matches_platformTparentsexist_okz-No skills found. Skills directory created at /)successrV   
categoriesmessageSKILL.mdc              3       K   | ]}|v V  	d S r;   r   r   partr   s     r   rx   z(_skills_list_from_dir.<locals>.<genexpr>   )      KKD4//KKKKKKr   utf-8encodingN  namer-   descriptionrI   
#rm   ...)r   r   r   disabledz Failed to read skill file %s: %sz)Skipping skill at %s: failed to parse: %sexc_infoc                 F    g | ]}|                     d           k    |S r   r?   )r   r   r   s     r   r{   z)_skills_list_from_dir.<locals>.<listcomp>  s/    MMMAquuZ/@/@H/L/La/L/L/Lr   c              3   j   K   | ].}|                     d           |                     d           V  /dS )r   Nr   r   s     r   rx   z(_skills_list_from_dir.<locals>.<genexpr>  s?      WW!QUU:EVEVWAEE*--WWWWWWr   )r   rV   r   countz@Use skill_view(name) to see full content, tags, and linked fileshintz%No skills found in skills/ directory.r   ) r|   r   r\   r   r   r   r   r   r   rz   mkdirsetr   anyrn   parent	read_textr?   r   r   split
startswithro   addappendrr   UnicodeDecodeErrorPermissionErrorr   r   r[   sorted)rp   r   r   r   r   r   r   r   
all_skills
seen_namesr   search_dirsscan_dirrj   	skill_dircontentfrontmatterbodyr   r   lineer   resultr   s    `                      @r   _skills_list_from_dirr      s    988888                 
555TzTTT	
 
 	
 J55J((**H+J77K $ $..xDD #	 #	HKKKKHNKKKKK  I",,g,>>uuE$6$6w$?$?!T--k:: "vy~>>ssC:%%)oomR@@" " $

 2 24 8 8 " "#zz|| "(<(< "*.K!E{##&<<<"-.J0F0J.J"Ke"SKt$$$!! $'2$=h$T$T$(H$4	     '8 N N N?1MMMMMMMM   ?1W[         A#	J  NMMMMMMM
j))JWWzWWWWWXXJ Z	 F  D[vCyMs1   57G*-'G*CG**I;HI*IIr   c                 ^   ddl m} ddlmm} t          | pd                                                              d          }|sdS |g}d|v r7|                    dd          \  }}|r|r|                    | d|            |D ]}|	                                s|D ]}	||	z  }
t          ||
          s|
                                r"|
d	z  	                                r|
|
d	z  fc c S |
                    d
          }|	                                rt          ||          r|j        |fc c S  ||d	          D ]}t          fd|j        D                       r#|j        }|j        |k    r||fc c S 	  ||                    d          dd                   \  }}|                    d          |k    r||fc c S # t&          $ r Y w xY w|                    d          D ]6}|j        d	k    r|j        |k    rt          ||          r|j        |fc c S 7dS )z>Resolve a WebUI skill name inside explicit skills directories.r   r   )r   r   rI   r   NN:   r   z.mdc              3       K   | ]}|v V  	d S r;   r   r   s     r   rx   z&_find_skill_in_dirs.<locals>.<genexpr>I  r   r   r   r   Nr   r   *.md)r|   r   r\   r   r   r   r   r   r   rz   ri   is_dirwith_suffixr   r   rn   r   r   r?   r[   rglobstem)r   rk   r   r   raw_namecandidate_names	namespacebarerp   candidate_namedirect_path	legacy_mdrj   r   r   _r   s                   @r   _find_skill_in_dirsr   ,  s   888888JJJJJJJJ4:2$$&&,,S11H zjO
h"..a00	4 	: 	:""i#8#8$#8#8999! 3 3
  "" 	- 	3 	3N$~5K%j+>> !!## =z)A(I(I(K(K ="K*$<<<<<<<#//66I!! 3&8Y&O&O 3 '222222..z:FF 	 	HKKKKHNKKKKK  I~)) (******!3!3H4F4FPW4F4X4XY^Z^Y^4_!`!`Q??6**h66$h...... 7    $))&11 	3 	3I~++~)).@Y.W.W) '222222		3
 :s   AG
GGc                 $    t          | |g          S )z?Resolve a WebUI skill name inside an explicit skills directory.)r   )r   rp   s     r   _find_skill_in_dirr   ]  s    tj\222r   c                     d t          |                              dg           d d         D             }dd|  d|ddS )	Nc                     g | ]
}|d          S r   r   r   s     r   r{   z,_skill_not_found_payload.<locals>.<listcomp>c  s    ]]]q6]]]r   rV      FSkill 'z' not found.z+Use skills_list to see all available skills)r   erroravailable_skillsr   )r   r?   )r   rp   	availables      r   _skill_not_found_payloadr   b  sa    ]]$9*$E$E$I$I(TV$W$WX[Y[X[$\]]]I-4---%=	  r   r   c                 N     r dz                                   si S i } dz  }|                                 r5 fd|                    d          D             }|rt          |          |d<    dz  }|                                 r\g }dD ]6}|                     fd|                    |          D                        7|rt          t          |                    |d<    dz  }|                                 r5 fd	|                    d
          D             }|rt          |          |d<    dz  }	|	                                 r\g }
dD ]6}|
                     fd|	                    |          D                        7|
rt          t          |
                    |d<   |S )Nr   
referencesc                 T    g | ]$}t          |                                        %S r   r   rf   r   fr   s     r   r{   z+_linked_files_for_skill.<locals>.<listcomp>s  s-    SSS!AMM),,--SSSr   r   	templates)r   *.pyz*.yamlz*.yml*.jsonz*.tex*.shc              3   \   K   | ]&}t          |                                        V  'd S r;   r   r   s     r   rx   z*_linked_files_for_skill.<locals>.<genexpr>{  s7      ]]qSy!9!9::]]]]]]r   assetsc                 |    g | ]8}|                                 t          |                                        9S r   )is_filer   rf   r   s     r   r{   z+_linked_files_for_skill.<locals>.<listcomp>  s?    ^^^ARSR[R[R]R]^#ammI..//^^^r   *scripts)r   r   z*.bashz*.jsz*.tsz*.rbc              3   \   K   | ]&}t          |                                        V  'd S r;   r   r   s     r   rx   z*_linked_files_for_skill.<locals>.<genexpr>  s7      XXQ3q}}Y7788XXXXXXr   )rz   globr   r}   r   r   )r   linked_filesreferences_dirrefstemplates_dirr   ext
assets_dirr   scripts_dirr   s   `          r   _linked_files_for_skillr  l  s	    Y3;;== 	)+L-N 6SSSS~7J7J67R7RSSS 	6)/L&+M ?	Q 	^ 	^C]]]]MDWDWX[D\D\]]]]]]] 	?(.s9~~(>(>L%X%J 4^^^^9I9I#9N9N^^^ 	4%+F^^L"i'K ;E 	Y 	YCNNXXXX+BRBRSVBWBWXXXXXXX 	;&,S\\&:&:L#r   c                 0   ddl m}m}m} |                    d          } ||          \  }} ||          sdddS |                    d          }t          |t                    r|                    d	i           ni }	 ||	                    d
          p|                    d
d                    }
 ||	                    d          p|                    dd                    }	 t          |	                    | p|j
        j
                            }n# t          $ r t          |          }Y nw xY wd|                    d| s|j        n| j                  |                    dd          |
|||| rt          |           nd t          |           d	S )Nr   )r   _parse_tagsr   r   r   Fz(Skill is not available on this platform.)r   r   metadatahermestagsrI   related_skillsTr   r   )	r   r   r   r  r  r   r    r   r  )r\   r   r
  r   r   r?   r=   r>   r   rf   r   rh   r   r   r  )r   rj   r   r
  r   r   r   _bodyr  hermes_metar  r  r    s                r   _skill_view_from_filer    s   YYYYYYYYYY  ' 22G++G44K!!+.. W +UVVVz**H0:8T0J0JR(,,x,,,PRK;{v..M+//&"2M2MNND [())R[__=Mr-R-R N8'')Eho(MNNOO   8}} Y(ZIN[["}b99('0:S^^^d/	::
 
 
s   *.D D54D5c                 6   ddl m} t                      }t          |          }t	          | |          \  }}|sdt          | pd          v r	 ddlm}m} ddl	m
}m}	  ||           \  }
} ||
          rt |              |	            }|                    |           |                    |
          r6 ||           }t          |t
                    rt          j        |          n|S n# t"          $ r Y nw xY wt%          | |          S t'          ||          S )Nr   )
skill_viewr   rI   )is_valid_namespaceparse_qualified_name)discover_pluginsget_plugin_manager)r\   r  ra   r   r   r   r|   r  r  hermes_cli.pluginsr  r  find_plugin_skilllist_plugin_skillsr=   jsonloadsr[   r   r  )r   _skill_viewrp   r   r   rj   r  r  r  r  r   _barepmrQ   s                 r   _skill_view_from_active_dirr     ss   ;;;;;;#%%J+J77K-dK@@Ix : #djb//!!VVVVVVVVSSSSSSSS#7#7#=#= 	5%%i00 P$$&&&++--B++D11=AVAVW`AaAa=)k$//2<S#2F2FOtz#CO   'j999 H555s   BC+ +
C87C8   c                 l    t          | pd                                                                          S NrI   r   
raw_sources    r   _normalize_messaging_sourcer&    s-    zR  &&((..000r   c                 .    t          |           t          v S r;   )r&  _MESSAGING_RAW_SOURCESr$  s    r   _is_known_messaging_sourcer)    s    &z226LLLr   c                  d    | D ],}|t          |                                          }|r|c S -dS r#  r   r   )valuesvaluetexts      r   _safe_firstr/    sK      =5zz!! 	KKK	2r   c            
         	 ddl m}  t           |                                                                                       }nw# t
          $ rj t          t          j        dt          t          j	                    dz                                                                                                }Y nw xY w|dz  dz  S )Nr   rT   rX   rY   sessionszsessions.json)
rZ   rU   r   r`   re   r[   r]   r^   r   r_   )rU   hermes_homes     r   _gateway_session_metadata_pathr3    s    j777777113344??AAIIKK j j j29]C	i8O4P4PQQRR]]__ggiij#o55s   AA A1B87B8c                     t                      } |                                 si S 	 |                                 }t          }t          5  |d         t          |           k    r7|d         |j        k    r&|d                                         cd d d            S d d d            n# 1 swxY w Y   n# t          $ r i cY S w xY w	 t          j
        |                     d                    }n5# t          $ r(}t                              d| |           i cY d }~S d }~ww xY wi }t          |t                    r|                                D ]}t          |t                    st#          |                    d                    }|s>t          |                    d          t                    r|                    d          ni }t#          |                    d	          |                    d	                    }	t#          |                    d
          |                    d                    t#          |                    d          |                    d                    t#          |                    d          |                    d                    t#          |                    d          |                    d                    t#          |                    d          |                    d                    |	|	d||<   t          5  t          |           t          d<   |j        t          d<   |t          d<   d d d            n# 1 swxY w Y   |                                S )Nr    r!   r"   r   r   z5Failed to parse gateway sessions metadata from %s: %sr5   originplatformsession_keykeychat_id	thread_id	chat_typeuser_id)r7  r9  r:  r;  r<  r6  r%  )r3  rz   statr#    _MESSAGING_SESSION_METADATA_LOCKr   st_mtimecopyr[   r  r  r   r   r   r=   r>   r,  r/  r?   )
r    stcacheraw_sessions	_json_errmapping_entryr5   r5  r6  s
             r   "_load_gateway_session_identity_maprG    s   )++D;;== 	YY[[1- 	0 	0V}D		))eGn.K.KZ(--//	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0    			z$..'."B"BCC   LdT]^^^						  "G,%% "))++ 	 	Ffd++ $VZZ%=%=>>J -7

88L8Ld-S-S[VZZ)))Y[F"6::j#9#96::j;Q;QRRH*6::m+D+DfjjQVFWFWXX&vzz)'<'<fjj>S>STT(K)@)@&**[BYBYZZ(K)@)@&**[BYBYZZ&vzz)'<'<fjj>S>STT$&# #GJ 
* @ @47II)&157[)'28?)*5@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ <<>>sl   "B1 AB%B1 B1 %B))B1 ,B)-B1 1C ?C (C- -
D7DDD1MMMjob_idc                 |    t           5  t          j                    t          | <   d d d            d S # 1 swxY w Y   d S r;   )_RUNNING_CRON_LOCKtimer   rH  s    r   _mark_cron_runningrM  #  s}    	 1 1%)Y[[6"1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1   155c                 |    t           5  t                              | d            d d d            d S # 1 swxY w Y   d S r;   )rJ  r   poprL  s    r   _mark_cron_donerQ  (  s    	 - -vt,,,- - - - - - - - - - - - - - - - - -rN  c                     t           5  t                              |           }|	 ddd           dS dt          j                    |z
  fcddd           S # 1 swxY w Y   dS )z%Return (is_running, elapsed_seconds).N)F        T)rJ  r   r?   rK  )rH  ts     r   _is_cron_runningrU  -  s    	 % %""6**9% % % % % % % % TY[[1_$	% % % % % % % % % % % % % % % % % %s   AAAAr.  c                     g }dD ]b}|                      |          r|                    d           |                     d|           }|dk    r|                    |dz              c|rt          |          ndS )zBReturn the start index of a markdown Response heading, if present.)## Response
# Responser   r   r   )r   r   findmin)r.  
candidatesheadingidxs       r   _cron_response_marker_indexr_  6  s    J0 ' '??7## 	!a   iiW''!88cAg&&&(03z???b0r   limitc                 >   |dk    rdS t          |           |k    r| S t          |           }|dk    ra| dt          t          |                                                   }| |d                             d          }|r| d| n|}|d|         S | | d         S )a7  Return a bounded cron output window that preserves useful response text.

    Cron output files can contain large skill dumps in the Prompt section. The
    UI already extracts ``## Response`` when present, so keep that section in
    the API payload instead of blindly returning the first ``limit`` chars.
    r   rI   Nr   z
...
)ro   r_  r[  _CRON_OUTPUT_HEADER_CONTEXTrstriplstrip)r.  r`  response_idxheaderresponser   s         r   _cron_output_content_windowrh  B  s     zzr
4yyE.t44LqEs6EEEFMMOO&--d3328FV..H...hvv=r   jobc                     t          | pi           }|                    dd           |                    d          du|d<   |S )a  Return a cron job payload with optional UI settings normalized.

    Legacy jobs intentionally persist without ``profile`` so they keep the
    scheduler's server-default behavior. The API still returns ``profile: None``
    so the UI can label that state explicitly instead of guessing.

    ``toast_notifications`` is a WebUI preference for completion toasts. Legacy
    jobs default to enabled so existing behavior is preserved unless a job is
    explicitly muted.
    profileNtoast_notificationsF)r>   
setdefaultr?   )ri  r   s     r   _cron_job_for_apirn  Z  sK     39"ooGy$'''%,[[1F%G%Gu%TG!"Nr   c                     d | pg D             S )Nc                 ,    g | ]}t          |          S r   )rn  )r   ri  s     r   r{   z&_cron_jobs_for_api.<locals>.<listcomp>l  s!    ;;;sc"";;;r   r   )jobss    r   _cron_jobs_for_apirr  k  s    ;;tzr;;;;r   c                      ddl m}  dh} |             D ]a}	 t          |                    d          pd                                          }n# t
          $ r Y Fw xY w|r|                    |           b|S )Nr   )list_profiles_apirC   r   rI   )rZ   rt  r   r?   r   AttributeErrorr   )rt  namesrk  r   s       r   _available_cron_profile_namesrw  o  s    ......KE$$&&  	w{{6**0b117799DD 	 	 	H	 	IIdOOOLs   6A
AAc                     | d S t          |                                           }|sd S |t                      vrt          d|           |S )NzUnknown profile: )r   r   rw  rh   )r-  rk  s     r   _normalize_cron_profile_valuery  }  s^    }t%jj  G t355556W66777Nr   c                 H   ddl m}m} t          | pi                     d          pd                                          }|s
 |            S |t                      vr<t                              d| pi                     dd          |            |            S  ||          S )a2  Resolve the execution profile for a cron job, with graceful fallback.

    A missing/blank profile preserves legacy server-default behavior. If a job
    points at a profile that was deleted after save, fall back to the active
    server profile and log a warning instead of crashing the Run Now path.
    r   )rU   get_hermes_home_for_profilerk  rI   zICron job %s references missing profile %r; falling back to server defaultid?)	rZ   rU   r{  r   r?   r   rw  r   warning)ri  rU   r{  rQ   s       r   _profile_home_for_cron_jobr    s     QPPPPPPP
sybooi((.B
/
/
5
5
7
7C (%%'''
/1111WYBOOD#&&	
 	
 	
 &%'''&&s+++r   c                 |    	  fd}| |            }n3ddl m}  ||          5   |            }ddd           n# 1 swxY w Y   |                    d|f           dS # t          $ rP}ddl}|                    dt          |          j         d| |                                f           Y d}~dS d}~ww xY w)zARun one cron job inside a child process pinned to a profile home.c                  &    ddl m}   |           S )Nr   )run_job)cron.schedulerr  )r  ri  s    r   _runz'_cron_job_subprocess_main.<locals>._run  s#    ......73<<r   Nr   cron_profile_context_for_homeokr   z: )rZ   r  putBaseException	tracebacktype__name__
format_exc)ri  execution_profile_homeresult_queuer  r   r  excr  s   `       r   _cron_job_subprocess_mainr    sX   \	  	  	  	  	 
 ")TVVFFBBBBBB../EFF                                 $((((( \ \ \'d3ii&8#A#AC#A#A9CWCWCYCYZ[[[[[[[[[\s8   #A! =A! AA! AA! !
B;+AB66B;c                     dD ]a}| pi                      |          }|dv r	 t          |          }n# t          t          f$ r Y Bw xY w|dk    rt	          d|dz             c S bdS )zFReturn how long the manual-run parent waits for child result payloads.)timeout_secondsmax_runtime_secondstimeoutr#  r         N@      >@g     @)r?   float	TypeErrorrh   max)ri  r8  rQ   r-  s       r   '_cron_subprocess_result_timeout_secondsr    s    D 	+ 	+ybooc""*	#JJEE:& 	 	 	H	199tUT\*****  =s   2AAc                    ddl }ddl}|                    d          }|                    d          }|                    t
          | ||f          }|                                 t          |           }d}dd	g}		 	 |                    |
          ^}}	ng# |j	        $ rZ d}|
                                r4|                                 |                    d
           d|ddd	g}	nd|j         dd	g}	Y nw xY w|                    d
           |
                                r6|                                 |                    d
           |dk    rd}dd	g}	ne# |                    d
           |
                                r6|                                 |                    d
           |dk    rd}dd	g}	w xY w|                                 |                                 n-# |                                 |                                 w xY w|dk    r|	d         S |	d         }
t!          |	          dk    r|	d         nd	}|rt"                              d|           t'          |
          )a  Execute cron.scheduler.run_job without holding the parent cron env lock.

    cron.scheduler/cron.jobs still rely on process-global HERMES_HOME and module
    constants, so running the job body in a child process gives each long cron
    execution its own globals. The parent process only uses cron_profile_context
    for short metadata reads/writes and remains responsive to unrelated cron UI
    and API calls while the job runs.
    r   Nspawnr   maxsize)targetargsr   z4cron run subprocess failed before producing a resultrI   r  r!  z.cron run subprocess produced no result within gzs and was terminatedz%cron run subprocess exited with code z without producing a resultr  z9cron run subprocess did not exit after returning a resultz!Manual cron subprocess failed:
%s)multiprocessingqueueget_contextQueueProcessr  startr  r?   Emptyis_alive	terminatejoinexitcodeclosejoin_threadro   r   r   RuntimeError)ri  r  r  r  ctxr  processresult_timeoutstatusr   r   traceback_texts               r   #_run_cron_job_in_profile_subprocessr    s    LLL

%
%g
.
.C99Q9''Lkk()<8   G MMOOO<SAANFErJG"#	
  ,///GGFWW{ 	 	 	F!! !!###Q'''k^kkkk jG<Liii	 LLL###!! !!###Q'''T>>$FSG LLL###!! !!###Q'''T>>$FSG    
 	  """" 	  """"~~qzajG#&w<<!#3#3WQZZN K9>JJJ
w

s?   >B E A!C;8E :C;;E >A!G- A"GG- -*Hc           
         	
 ddl }ddlmm |                    d          }t          |dd          t          |dd                               dd	          |p|}d
 }	 t           |          \  

 f
d} |||           np# t          $ rc	t          
                    d           	  ||	fd           n+# t          $ r t                              d           Y nw xY wY d		nd		ww xY wt                     t          d           dS # t                     t          d           w xY w)as  Wrapper that tracks running state around cron.scheduler.run_job.

    ``profile_home`` is the cron store that owns the job row/output metadata.
    ``execution_profile_home`` is the selected per-job profile used to load
    agent config/.env while running. When no job profile is selected, both homes
    are the same and legacy server-default behavior is preserved.
    r   N)mark_job_runsave_job_outputzcron.schedulerSILENT_MARKERz[SILENT]_deliver_resultr|  rI   c                     | 
 |            S ddl m}  ||           5   |            cd d d            S # 1 swxY w Y   d S )Nr   r  )rZ   r  )r_   fnr  s      r   _with_cron_homez*_run_cron_tracked.<locals>._with_cron_home  s    <244K>>>>>>**400 	 	244	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   
599c                    
             r	nd
                     d           d } t          |           }|r,r*|                                                                 v rd}d }|rRP	  
|           }nB# t          $ r5}t          |          }t                              d|           Y d }~nd }~ww xY w}}|r	sd}d}	  |||           d S # t          $ r  ||           Y d S w xY w)Nu   ⚠️ Cron job 'r   z
' failed:
Fz*Delivery failed for manual cron job %s: %szWAgent completed but produced empty response (model error, timeout, or misconfiguration))delivery_error)	r?   boolr   upperr[   r   r   r   r  )deliver_contentshould_deliverr  de_success_errorr  _silent_markerr   final_responseri  rH  r  outputr  r   s         r   _persist_successz+_run_cron_tracked.<locals>._persist_success-  s   OFF+++ UT)@)@TTUTT 
 "/22N '' 'n@U@U@W@W@]@]@_@_._._!&!N [/"=[%4_S/%J%JNN  [ [ [%(WWNLL!MvWYZZZZZZZZ[  'fH s s r7VXvnUUUUUU 7 7 7
 VXv6666667s*   2A? ?
B>	+B99B>C C:9C:z!Manual cron run failed for job %sc                  8     dt                               S NFr   )r   rH  r  s   r   <lambda>z#_run_cron_tracked.<locals>.<lambda>U  s    ,,vucRSff2U2U r   z-Failed to mark manual cron run failure for %scron_complete)	importlib	cron.jobsr  r  import_moduler@   r?   r  r[   r   	exceptionr   rQ  r   )ri  profile_homer  r  _cron_schedulerr  r  r  r  r   r   r  rH  r  r  r  r   s   `      @@@@@@@@@@r   _run_cron_trackedr  	  s    77777777--.>??O_ozJJNo/@$GGOWWT2F3C|  561T'2
 2
."	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7 "	7H 	&67777 R R R<fEEE	ROL*U*U*U*U*U*UVVVV 	R 	R 	RLLH&QQQQQ	R	R 	$_55555 	$_5555sT   -/B D- 
D
'DCD%C=:D<C==D D- D

D- - E	anthropicopenaigoogle)claudegptgeminiopenai-codexzhttps://api.z.ai/v1zhttps://api.minimax.chat/v1zhttps://api.mistral.ai/v1zhttps://api.x.ai/v1zhttps://api.deepseek.comz7https://generativelanguage.googleapis.com/v1beta/openaiz#https://integrate.api.nvidia.com/v1)zaiminimax	mistralaixaideepseekr  nvidiar  _LIVE_MODELS_CACHEc                      	 ddl m}   |             pdS # t          $ r&}t                              d|           Y d }~dS d }~ww xY w)Nr   get_active_profile_namerC   z@_active_profile_for_live_models_cache fell back to 'default': %s)rZ   r  r[   r   r   )r  _es     r   %_active_profile_for_live_models_cacher  z  sq    	888888&&((5I5    	WY[\\\yyyyys    
A?Aproviderc                 "    t                      | fS r;   )r  )r  s    r   _live_models_cache_keyr    s    133X>>r   r8  c                 ^   t          j                    }t          5  t                              |           }|s	 d d d            d S |\  }}||z
  t
          k    r)t                              | d            	 d d d            d S t          j        |          cd d d            S # 1 swxY w Y   d S r;   )	rK  	monotonic_LIVE_MODELS_CACHE_LOCKr  r?   _LIVE_MODELS_CACHE_TTLrP  r@  deepcopy)r8  nowcachedtsr   s        r   _get_cached_live_modelsr    s*   
.

C	  & &#'',, 	& & & & & & & & G8---""3---& & & & & & & & }W%%& & & & & & & & & & & & & & & & & &s   B"/B"B""B&)B&r   c                     t           5  t          j                    t          j        |          ft
          | <   d d d            d S # 1 swxY w Y   d S r;   )r  rK  r  r@  r  r  )r8  r   s     r   _set_cached_live_modelsr    s    	  M M#'>#3#3T]75K5K"L3M M M M M M M M M M M M M M M M M Ms   0AA	A	c                  x    t           5  t                                           d d d            d S # 1 swxY w Y   d S r;   )r  r  clearr   r   r   _clear_live_models_cacher    s~    	  # #  """# # # # # # # # # # # # # # # # # #s   /33)(	STATE_DIRSESSION_DIRDEFAULT_WORKSPACEDEFAULT_MODELSESSIONSSESSIONS_MAXLOCKSTREAMSSTREAMS_LOCKCANCEL_FLAGSSTREAM_LAST_EVENT_IDSERVER_START_TIME_resolve_cli_toolsets_INDEX_HTML_PATHget_available_models
IMAGE_EXTSMD_EXTSMIME_MAPMAX_FILE_BYTESMAX_UPLOAD_BYTES	CHAT_LOCK_get_session_agent_lockSESSION_AGENT_LOCKSSESSION_AGENT_LOCKS_LOCKload_settingssave_settingsset_hermes_default_modelmodel_with_provider_contextget_reasoning_statusset_reasoning_displayset_reasoning_effortcreate_stream_channelget_webui_session_save_modeSTREAM_GOAL_RELATEDPENDING_GOAL_CONTINUATION_get_config_path_load_yaml_config_file_save_yaml_config_filereload_config	_cfg_lock)
requirebadsafe_resolvejrT  	read_body_security_headers_sanitize_errorredact_session_data_redact_text)build_agent_health_payload)RequestDiagnostics)build_system_health_payloadmethodc                 B    t          | d| d|j         dd          pdS )zHReturn a Kanban-specific 404 for stale clients/obsolete endpoint shapes.zunknown Kanban endpoint:  z. If this appeared after a WebUI update, your browser may be running a stale cached bundle; use Hard refresh now, then reopen Kanban.  r  T)r&  r    )handlerparsedr1  s      r   _kanban_unknown_endpointr8    sU    O O O O O O     
r   c                 P   t          | dd          }|sdS t          5  |t          v }ddd           n# 1 swxY w Y   |rdS | }t          | dd          r	 ddlm}  || j        d          } n<# t          $ r/ t                              d|t          | d	d
                     Y dS w xY w| dS t          | dd          s`	 d|_	        t          |d          rd|_        t          |d          rg |_        t          |d          rd|_        n# t          $ r Y nw xY wdS t          | j                  5  t          | dd          |k    r	 ddd           dS t          | dd          r	 ddlm}m}  |t          | dd                    }|dz  d| j         dz  } || ||d          }	n=# t          $ r0 t                              d|t          | d	d
                     d}	Y nw xY w|	rp|| ur^	 d|_	        t          |d          rd|_        t          |d          rg |_        t          |d          rd|_        n# t          $ r Y nw xY w	 ddd           dS t          | dd          |k    r	 ddd           dS t%          |            d| _	        t          | d          rd| _        t          | d          rg | _        t          | d          rd| _        	 |                     d           n:# t          $ r- t                              dt          | d	d
                     Y nw xY wddd           n# 1 swxY w Y   || ur^	 d|_	        t          |d          rd|_        t          |d          rg |_        t          |d          rd|_        n# t          $ r Y nw xY wdS )a  Clear persisted streaming flags when the in-memory stream no longer exists.

    A server restart or worker crash can leave active_stream_id/pending_* in the
    session JSON while STREAMS is empty. The frontend then keeps reconnecting to
    a dead stream and shows a permanent running/thinking state.

    SAFETY (#1558): If ``session`` was loaded with ``metadata_only=True``, its
    ``messages`` array is empty by design and calling ``save()`` would
    atomically overwrite the on-disk JSON, wiping the conversation. In that
    case we re-load the full session before mutating, so the persisted
    write carries the real messages forward.
    active_stream_idNF_loaded_metadata_onlyr   r   r   u   _clear_stale_stream_state: refused to clear stale stream %s for session %s — full reload failed and we will not save a metadata-only stub. See #1558.r5   r}  pending_user_messagepending_attachmentspending_started_at) _apply_core_sync_or_error_marker_get_profile_homerk  r1  session_.json)stream_id_for_rechecktouch_updated_atzR_clear_stale_stream_state: failed to repair stale pending stream %s for session %sTrE  z7_clear_stale_stream_state: save() failed for session %s)r@   r  r  
api.modelsr   r5   r[   r   r~  r:  hasattrr=  r>  r?  r  r@  rA  r  +_materialize_pending_user_turn_before_errorsave)
rA   r6   stream_aliveoriginal_stub_get_sessionr@  rA  r  	core_pathrepaireds
             r   _clear_stale_stream_staterP    s    !3T::I u	 , , G+, , , , , , , , , , , , , , , u M w/77 "	>>>>>>"l7#5UKKKGG 
	 
	 
	 NN1 77L#>>	   55
	 ?5 w 2D99 	
	15.=*@AA >9=M6=*?@@ ;8:M5=*>?? <7;M4   5 
!!3	4	4 5 57.55BB5 5 5 5 5 5 5 5 72D99  	!ZZZZZZZZ00)T1R1RSS(:58\7CU8\8\8\\	;;*3%*	    ! ! !  %wwcBB  
 !!   //	9=6"=2HII FAEM>"=2GHH C@BM="=2FGG D?CM<$   C5 5 5 5 5 5 5 5D w 2D99YFFG5 5 5 5 5 5 5 5H 	4G<<<#' 7233 	0+/G(7122 	-*,G'7011 	.)-G&		 LL%L0000 	 	 	Is33    	c5 5 5 5 5 5 5 5 5 5 5 5 5 5 5p G##		-1M*}&<== :592}&;<< 7461}&:;; 8370 	 	 	D	4s   
377A/ /5B('B(AD 
DD4L9L9+AF.-L9.7G(%L9'G((	L92AH?>L9?
I	L9IL9L9 AL9K32L934L*'L9)L**L99L= L=	AN 
N#"N#FactivesummaryrR  c                N   t          |                     d                    }|                     d          }|s|sd}|                     d          |                     d          |                     d          |                     d          |                     d          ||d	S )
Nterminalterminal_statezlost-worker-bookkeepingr5   run_idlast_seqlast_event_id
last_event)r5   rW  rX  rY  rZ  rU  rV  )r  r?   )rS  rR  rU  rV  s       r   _run_journal_status_payloadr[  t  s    GKK
++,,H[[!122N 3( 32kk,//++h''KK
++ _55kk,//(  r   c                    t          |dd          s|S t          j        |           }|t          |           t          5  |t
          | <   t          j        |            t          t
                    t          k    r2t          j	        d           t          t
                    t          k    2ddd           n# 1 swxY w Y   |S )a`  Reload cached metadata-only sessions before mutating persisted fields.

    Session.save() intentionally refuses metadata-only stubs (#1558) because
    their messages list is empty by design. Mutation routes that save session
    metadata must upgrade the cached stub first so they do not trip that guard
    or risk writing an incomplete object.
    r;  FNlast)
r@   Sessionloadr   r  r  move_to_endro   r  popitem)r   rA   full_sessions      r   $_ensure_full_session_before_mutationrd    s     73U;; <$$Lsmm	 ) )$S!!!(mml**%(((( (mml**) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 s    A.B::B>B>c                 r   d}| D ]}t          |t                    s|                    d          }|r|                    d          sE|                    d          du r]	 t          |d          }n-# t          $ r  t
                              d|d           Y w xY w|t          |          p|}|S )	zIClear stale persisted stream fields before /api/sessions serializes rows.Fr5   r:  is_streamingTr   z>Failed to load session %s while reconciling stale stream stater   )r=   r>   r?   r   r[   r   r   rP  )session_rowschangedrowr   rA   s        r   ._reconcile_stale_stream_state_for_session_rowsrj    s    G @ @#t$$ 	ggl## 	#''"455 	77>""d**	!#T:::GG 	 	 	LLP    
 H	 ?+G44?Ns   #A55'BBr-  c                    |                                                                  } | sdS |                     d          rs|                     d          }|dk    rX| d|         }| |dz   d         }|                    d          r(|dd                                         r||dd         fS |dfS |                     d          dk    r1|                     dd          \  }}|                                r||fS | dfS )zpSplit a host or host:port string into (hostname, port|None).
    Handles IPv6 bracket notation, e.g. [::1]:8080.)rI   N[]rY  r   Nr   )r   r   r   rZ  isdigitr   rsplit)r-  endhostrestports        r   _normalize_host_portrt    s    KKMM!!E x jjoo"993<Dq#Ds## &QRR(8(8(:(: &T!""X~%:{{31\\#q))
d<<>> 	:$;r   origin_schemeorigin_portallowed_portc                 R    ||k    rdS | dk    rdnd}|s||k    rdS |s||k    rdS dS )a  Return True when two ports should be considered equivalent, scheme-aware.

    Treats an absent port as the scheme default: port 80 for http, port 443 for https.
    Port 80 is NOT treated as equivalent to 443 (different protocols = different origins).
    Thttps44380Fr   )ru  rv  rw  rC   s       r   _ports_matchr|    sZ     l""t$//eeTG <722t K722t5r   c                     t          j        dd          } t                      }|                     d          D ]}|                                                    d                                          }|s>|                    d          s5|                    d          s ddl}t          d	|d
d|j
                   |                    |           |S )zParse HERMES_WEBUI_ALLOWED_ORIGINS env var (comma-separated) into a set.

    Each entry must include the scheme, e.g. https://myapp.example.com:8000.
    Entries without a scheme are silently skipped and a warning is printed.
    HERMES_WEBUI_ALLOWED_ORIGINSrI   ,r   http://https://r   Nz4[webui] WARNING: HERMES_WEBUI_ALLOWED_ORIGINS entry zU is missing the scheme (expected https://hostname or http://hostname). Entry ignored.T)flushfile)r]   r^   r   r   r   rc  r   r   sysprintstderrr   )rQ   r   r-  r  s       r   _allowed_public_originsr    s     )2B
7
7CUUF3  $$S))//11 	  ++ 	u/?/?
/K/K 	JJJ]u ] ] ]   
 

5Mr   c                     t          | j                            d          p| j                            d                    S )ai  Return True when request headers identify a browser unsafe request.

    Non-browser API clients, including the MCP bridge and curl-style scripts,
    normally send no Origin/Referer and remain compatible with the existing
    same-machine API contract. Browsers send Origin for unsafe fetch/form POSTs;
    Referer is retained for older paths and proxies.
    OriginReferer)r  headersr?   r6  s    r   _is_browser_unsafe_requestr    s7     ##H--O1D1DY1O1OPPPr   r    c                 
    | dv S )z9Paths that cannot or must not carry a session CSRF token.>   /api/auth/login/api/csp-report/api/auth/passkey/login/api/auth/passkey/optionsr   r    s    r   _csrf_exempt_pathr    s       r   _hermes_csrf_failure_reasonr9   c                 V    	 t          | t          |           n# t          $ r Y nw xY wdS r  )setattr_CSRF_FAILURE_ATTRr[   r6  r9   s     r   _set_csrf_failure_reasonr    sB    +V4444   5s    
&&c                     	 t          | t                    rt          | t                     d S d S # t          $ r Y d S w xY wr;   )rH  r  delattrr[   r  s    r   _clear_csrf_failure_reasonr    s]    7.// 	1G/00000	1 	1   s   *0 
>>c                 R    t          | t          d          }|dk    rdS |dk    rdS dS )NrI   origin_mismatchz3Cross-origin mismatch - check reverse proxy headerstoken_mismatchz!Session expired - reload the pageCross-origin request rejected)r@   r  r  s     r   _csrf_rejection_errorr    s>    W0"55F"""DD!!!22**r   c                    t          |            | j                            dd          }| j                            dd          }| j                            dd          }t          |           sdS |p|}t	          j        d|          }|st          | d          S |                    d          }|                    d	                              d
          d	         	                                }t          |          \  }}	d}
|                    d	                              d          	                                }|t                      v rd}
|
ssd || j                            dd          | j                            dd          fD             }|D ]/}t          |          \  }}||k    rt          ||	|          rd}
 n0|
st          | d          S d	dlm}m}m}m}  |            sdS  ||           }| j                            |          p| j                            d          } ||pd|pd          rdS t          | d          S )zGReject cross-origin or tokenless authenticated browser unsafe requests.r  rI   r  HostTz^https?://([^/]+)r  r   r   z://Fr   c                 ^    g | ]*}|                                 |                                 +S r   r   )r   hs     r   r{   z_check_csrf.<locals>.<listcomp>>  s@     
 
 

 wwyy
GGII
 
 
r   zX-Forwarded-HostzX-Real-Host)CSRF_HEADER_NAMEis_auth_enabledparse_cookieverify_csrf_tokenzX-CSRF-Tokenr  )r  r  r?   r  _rematchr  groupr   r   rt  rc  r  r|  api.authr  r  r  r  )r6  r5  refererrq  r  morigin_hostru  origin_namerv  origin_allowedorigin_valueallowed_hostsallowedallowed_namerw  r  r  r  r  
cookie_val	submitteds                         r   _check_csrfr  %  s   w'''_  2..Fo!!)R00G?vr**D%g.. twF	&//A D'1BCCC''!**KGGAJJ$$U++A.4466M3K@@KN771::$$S))//11L.0000 
 
 ##$6;;##M266
 
 
 % 	 	G)=g)F)F&L,l**|M;Xd/e/e*!% D'1BCCC[[[[[[[[[[[[? tg&&J##$455\9L9L^9\9\I)r9?;; t#G-=>>>r   c                 z    	 t          | dd           }|rt          |d                   S n# t          $ r Y nw xY wdS )Nclient_addressr   unknown)r@   r   r[   )r6  addresss     r   _client_ip_for_rate_limitr  Z  s[    '#3T:: 	#wqz??"	#   9s   '+ 
88)r  r  c                   |t          j                     n|}t          |           }|t          z
  t          5  fdt                              |g           D             }t          |          t          k    r|t          |<   	 d d d            dS |                    |           |t          |<   d d d            n# 1 swxY w Y   dS )Nc                      g | ]
}|k    |S r   r   r   r  cutoffs     r   r{   z,_csp_report_rate_limited.<locals>.<listcomp>i  s    WWWR"PV,,b,,,r   TF)	rK  r  %_CSP_REPORT_RATE_LIMIT_WINDOW_SECONDS_CSP_REPORT_RATE_LIMIT_LOCKr'   r?   ro   _CSP_REPORT_RATE_LIMIT_MAXr   r6  r  r8  
timestampsr  s       @r   _csp_report_rate_limitedr  d  s#   $)+++#C
#G
,
,C88F	$ 1 1WWWW#9#=#=c2#F#FWWW
z??888*4"3'	1 1 1 1 1 1 1 1
 	#&0s#1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5   AB<B<<C C c                   |t          j                     n|}t          |           }|t          z
  t          5  fdt                              |g           D             }t          |          t          k    r|t          |<   	 d d d            dS |                    |           |t          |<   d d d            n# 1 swxY w Y   dS )Nc                      g | ]
}|k    |S r   r   r  s     r   r{   z._client_event_rate_limited.<locals>.<listcomp>w  s    YYYRBRXLLbLLLr   TF)	rK  r  '_CLIENT_EVENT_RATE_LIMIT_WINDOW_SECONDS_CLIENT_EVENT_RATE_LIMIT_LOCKr+   r?   ro   _CLIENT_EVENT_RATE_LIMIT_MAXr   r  s       @r   _client_event_rate_limitedr  r  s#   $)+++#C
#G
,
,C::F	& 3 3YYYY#;#?#?R#H#HYYY
z??:::,6$S)	3 3 3 3 3 3 3 3
 	#(2 %3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5r     r  c                     |                      |           |                     dd           |                                  dS )NContent-Length0T)send_responsesend_headerend_headers)r6  r  s     r   _send_no_contentr    sD    &!!!(#...4r   c                    	 t          | j                            dd                    }n# t          $ r d}Y nw xY w|t          k    r6	 | j                            t                     n# t          $ r Y nw xY wd|dS |r| j                            |          nd}	 t          j        |	                    d                    S # t          $ r dt          |          dcY S w xY w)	Nr  r   body_too_large)	discardedbytes   {}r   T)invalidr  )intr  r?   r[   _CSP_REPORT_MAX_BODY_BYTESrfilereadr  r  decodero   )r6  lengthrQ   s      r   _read_csp_report_payloadr    s   W_(()91==>>   ***	M9:::: 	 	 	D	-???(.
9'-

V
$
$
$EC4z#**W--... 4 4 4#c((333334s0   (+ ::	A) )
A65A6&C C#"C#c                    t          |           r7t                              dt          |                      t	          |           S t          |           }t                              dt          |           |           t	          |           S )zBCollect browser CSP report-only violations without requiring auth.z/Dropped CSP report from %s: rate limit exceededzCSP report from %s: %s)r  _CSP_REPORT_LOGGERr~  r  r  r  info)r6  r   s     r   _handle_csp_reportr    s    (( )""=%g..	
 	
 	
  (((&w//G46OPW6X6XZabbbG$$$r   c                 h    | d S t          |                                           }|sd S |d |         S r;   r+  r-  r`  r.  s      r   _bounded_client_event_stringr    s>    }tu::D t<r   c                 >   t          | d          }|sd S 	 t          |          }|j        pd}n.# t          $ r! |                    dd          d         pd}Y nw xY w|                    d          sd|                    d          z   }|d t          d                  S )N   r   r}  r   r   r8   )r  r   r    r[   r   r   rd  _CLIENT_EVENT_ALLOWED_FIELDS)r-  r.  r7  r    s       r   _sanitize_client_event_url_pathr    s    't44D t,${!c , , ,zz#q!!!$+,??3 &T[[%%%:.z::;;s   / (AAc                    t          | t                    sddiS i }t                                          D ]X\  }}|dk    r#t	          |                     |                    }n#t          |                     |          |          }||||<   Y|                     d          }t          |t                    rn*t          |t                    rd|cxk    rdk    rn n||d<   |                     d          }t          |t                    r||d<   nNt          |t                    r9|
                                                                }|d	v rd
|d<   n	|dv rd|d<   d|vrd|d<   |S )a1  Whitelist tiny browser diagnostic events and discard sensitive content.

    Client-side SSE diagnostics should explain transport failures without
    persisting prompts, cookies, query strings, headers, or arbitrary browser
    payloads. This helper intentionally keeps only bounded scalar metadata.
    r3   r  r8   Nready_stater   rm   online>   rJ   rM   rL   rK   T>   r  noofffalseF)r=   r>   r  itemsr  r?   r  r  r  r   r   r   )r   	sanitizedrB   r`  r-  r  r  lowereds           r   _sanitize_client_event_payloadr    s    gt$$ $###%I4::<< % %uJ3GKK4F4FGGEE0U1C1CUKKE$Ie++m,,K+t$$ /	K	%	% /!{*?*?*?*?a*?*?*?*?*?#.	- [[""F&$ ($	(	FC	 	  (,,..&&((000"&Ih333"'Ihi&	'r   c                 "   	 t          | j                            dd                    }n# t          $ r d}Y nw xY w|t          k    rO	 | j                            t                     n# t          $ r Y nw xY w	 d| _        n# t          $ r Y nw xY wdddS |r| j                            |          nd}	 |                    d          }t          j
        |          }n# t          $ r d	d
dcY S w xY wt          |t                    r|nd	ddS )Nr  r   Tr  r  )r3   r9   r  r   r  invalid_json
not_object)r  r  r?   r[   _CLIENT_EVENT_MAX_BODY_BYTESr  r  close_connectionr  r  r  r=   r>   )r6  r  rQ   decodedr   s        r   _read_client_event_payloadr    sn   W_(()91==>>   ,,,	M;<<<< 	 	 	D		'+G$$ 	 	 	D	$0@AAA(.
9'-

V
$
$
$EC>**W%%*W%% > > >"n=====> $//a77yT`5a5aasB   (+ ::	A) )
A65A6:B 
BB6)C   C21C2r   c                 ^   t          |           r?t                              dt          |                      t	          | dddd          pdS t          |          }t                              dt          |           |           t	          | d|                    d	          d
          pdS )Nz1Dropped client event from %s: rate limit exceededFrate_limited)r  r     r5  TzClient event from %s: %sr3   )r  r3   )r  _CLIENT_EVENT_LOGGERr~  r  r(  r  r  r?   )r6  r   r   s      r   _handle_client_event_logr    s    !'** V$$?%g..	
 	
 	
 @@MMMUQUU,T22G8:ST[:\:\^efffWTGKK,@,@AABBJdJr   c                     t          | pd                                                                          }|sdS |t          v rt          |         S dD ]\  }}|                    |          r|c S dS )NrI   ))r  r  )r  r  )r  r  )r  r  )r  r  )r  r  )
openrouterr	  )customr
  )r   r   r   _PROVIDER_ALIASESr   )r-  rQ   prefix
normalizeds       r   _normalize_provider_idr  
  s    
ekr


 
 
"
"
(
(
*
*C r
 %%	  
 >>&!! 		 2r   catalogc                    t                      }t                      }|                     d          pg D ]}t          |                    d          pd                                                                          }|sM|                    |           t          |          }|r|                    |           ||fS )Ngroupsprovider_idrI   )r   r?   r   r   r   r   r  )r  raw_provider_idsnormalized_provider_idsr  rQ   r  s         r   _catalog_provider_id_setsr  !  s    !$(+X&&," 4 4%))M**0b117799??AA 	S!!!+C00
 	4#''
333444r   provider_rawprovider_normalizedr  r  c                 "    | |v p|o||v p|o||v S r;   r   )r  r  r  r  s       r   _catalog_has_providerr  /  s<     	(( 	TK$7;K$K	TR$7;R$Rr   modelactive_providerc                     |                                  }dD ],}|                    |          rt          |          |k    c S -dS )Nr  r  r  F)r   r   r  )r  r  model_lowerbare_prefixs       r   %_model_matches_active_provider_familyr   <  s]     ++--K2 J J!!+.. 	J)+66/IIII	J5r   c                    t          | pd                                          } |                     d          r d| v r|                     dd          d         } d| v r|                     dd          d         } |                     dd                                          |                    dd                                          k    S )NrI   @r   r   r   -.)r   r   r   ro  r   replacer   )rc   r  s     r   _catalog_model_id_matchesr&  G  s    IO$$**,,IC   0SI%5%5$$S!,,Q/	
iOOC++A.	S#&&,,..%--S2I2I2O2O2Q2QQQr   c                     t          | pd                                                                          }|r|dk    rd S |                    d          r
|dd          }|pd S )NrI   rC   r"  r   )r   r   r   r   )r-  r  s     r   _clean_session_model_providerr(  P  sp    5;B%%''--//H x9,,t3  ABB<tr   c                    t          | pd                                          } |                     d          rPd| v rL| dd                              dd          \  }}t	          |          }|                                }|r|r||fS | d fS )NrI   r"  r   r   )r   r   r   ro  r(  )r  provider_hint
bare_modelr  r   s        r   _split_provider_qualified_modelr,  Y  s    ""$$E "$)!""I$4$4S!$<$<!z0??!! 	" 	">!$;r   raw_active_providerc                     |dk    rdS                                                       d          sdS |                    d          pg D ]}t          |                    d          pd                                                                           dk    rOt           fd|                    dg           D                       c S dS )	a  Return True when a bare Codex model needs separate provider context.

    OpenAI, OpenAI Codex, Copilot, and OpenRouter can all expose GPT-looking
    bare names. If a session stores only ``gpt-...`` while Codex is active, a
    later provider-list/default-model round trip can lose the user's Codex
    choice. Store the provider separately instead of converting the persisted
    model to ``@openai-codex:model``.
    r  Fr  r  r  rI   c              3      K   | ]<}t          |t                    t          |                    d                     V  =dS r|  N)r=   r>   r&  r?   )r   entryr  s     r   rx   z8_should_attach_codex_provider_context.<locals>.<genexpr>t  s[       
 
%&&
%eiioou==
 
 
 
 
 
r   models)r   r   r?   r   r   r   )r  r-  r  r  s   `   r   %_should_attach_codex_provider_contextr3  d  s     n,,u;;==##E** uX&&," 
 
uyy''-2..4466<<>>.PP 
 
 
 
8R00
 
 
 
 
 	
 	
 	

 5r   model_idmodel_providerc                 @   t          | pd                                          }t          |          }|ro|rmt          |          \  }}d|v r@|                    dd          d                                                                         nd}|dk    o|dk    }|s|s||dfS t                      }t          |                    d          pt          pd                                          }	|s|	|t          |	          fS t          |                    d	                    }
t          |                    d	          pd                                                                          }|
s|st          |          \  }}||p|dfS t          |          \  }}|ra|s_d|v r@|                    dd          d                                                                         nd}|dk    o|dk    o|dk    }|s||dfS |                    d
          rd|v r|pd}t          |          }|                                }|r|s||dfS t          |          \  }}||k    p||
k    p|o||
k    }|r||dfS t          ||||          r||dfS t          ||
          rt          |||          r|nd}||dfS |	rt          |	||          r|nd}|	|dfS ||dfS |                    d          }|dk     r|                                }dD ]h}|                    |          rQt          |          }|r$||
k    r|	rt          |	||          r|nd}|	|dfc S t          |||          r|n|}||dfc S i||dfS t          |d|                   }|
dv r\|dv r||dfS |                    d          pg }d |D             }t#          d |D                       }||v s|r||dfS |	r|	|dfS ||dfS |dk    r|dk    r|dv r|	r|	|dfS |
p|}|r|dvr||k    r|	r|	|dfS ||dfS )u}  Return (effective_model, effective_provider, model_was_normalized).

    Sessions can outlive provider changes. When an older session still points at
    a different provider namespace (for example `gemini/...` after switching the
    agent to OpenAI Codex), reusing that stale model causes chat startup to hit
    the wrong backend and fail. Normalize only obvious cross-provider mismatches.
    When a model has an explicit provider context, keep the model string itself
    in its picker/API shape and carry the provider as separate state.

    Fast path (#1855): when the caller supplies both a model and an explicit
    ``model_provider`` AND the model is not itself ``@provider:model``-qualified,
    we can return the inputs verbatim without calling ``get_available_models()``.
    The slow path below would arrive at the same answer via
    ``if requested_provider and not explicit_provider: return model, requested_provider, False``
    after paying the full catalog-build cost. Avoiding the catalog here keeps
    ``POST /api/chat/start`` snappy even when the model catalog is cold and the
    rebuild has to make network calls (custom OpenAI-compat endpoints,
    OpenRouter ``/models``, LM Studio ``/models``, credential pool refresh) —
    those used to wedge the handler for >100s and trigger 502s on default-60s
    reverse proxies, even though the WebUI itself eventually responded.
    rI   r   r   r   r  r  Fdefault_modelr  r"  r   NTr  >   r
  r	  >   rI   r
  r	  r  c                 V    h | ]&}t          |                    d           pd          'S )r  rI   )r  r?   r   r  s     r   r   z:_resolve_compatible_session_model_state.<locals>.<setcomp>  s?     !
 !
 !
CD"155#7#7#=2>>!
 !
 !
r   c              3   L   K   | ]}|                     d           pddk    V   dS )r  rI   r	  Nr   r9  s     r   rx   z:_resolve_compatible_session_model_state.<locals>.<genexpr>  sI       #
 #
=>QUU=!!'RL8#
 #
 #
 #
 #
 #
r   >   Nr  )r   r   r(  r,  r   r   r  r?   r   r  r  r   r  r  r   r3  rZ  r   )r4  r5  r  requested_providerr+  explicit_providermodel_prefixstale_codex_openai_slash_idr  r7  r  r-  bare_for_contextr  r  r  r  hint_matches_activeprovider_contextslashr  r  r  routable_provider_idshas_openrouter_group_active_for_compares                             r   '_resolve_compatible_session_model_staterF  |  sG   2 B%%''E6~FF 4# 4 )H(N(N%
%ADu{{3**1-3355;;===SU.0 )( 	$ ! 	4)D 	4,e33"$$GO44KKLLRRTTM F0$}2E2EEE,W[[9J-K-KLLO gkk*;<<BCCIIKKQQSS E#6 E(G(N(N%
%'=+=uDD*I%*P*P'' 4"3 4ADu{{3**1-3355;;===SU>1 )"n4)( 	$
 + 	4,e33 -*(.B4\BB%++--
 	4: 	4,e334Mg4V4V11// P.P#N(;(N 	
  	. ,-- #	
 
 	. ,--0_MM 	6 9EXZabb## 
 /55 	9 9H[]dee## 
 !"2D88lE))JJsOOEqyykkmm6 	6 	6K%%k22 6!7!D!D! An&G&GM&G APcelmm"++! %
 )*:D@@@@ =UDWY`aa,''+ !
 .55556 (%//+E&5&M::N 222999,e33X&&,"!
 !
HN!
 !
 !
  # #
 #
BH#
 #
 #
  
  
 2226J2,e33 	; "4d::(%// 	~--h&&"888 9 1477 *@-@ 7.0LLLQ_cvQvQv  |IQv0$66$e++r   c                 0    t          |           \  }}}||fS )zBReturn (effective_model, model_was_normalized) for legacy callers.)rF  )r4  effective_model	_providerrh  s       r   !_resolve_compatible_session_modelrJ  @  s"    *QRZ*[*['OYG##r   c                    t          | dd           pd}t          t          | dd                     }t          |pd |          \  }}}||k    }|r8|r6|r||k    s|r,|r||k    r|| _        || _        |                     d           |S )Nr  rI   r5  FrF  )r@   r(  rF  r  r5  rJ  )rA   original_modeloriginal_providerrH  effective_providerrh  provider_changeds          r   !_normalize_session_model_in_placerP  F  s    Wgt44:N5)400  4[$4 40O' *->>  -/ -	-#66;K6 	,~88+GM!3e,,,r   c                 z    t          | dd          pd}t          |pdt          | dd                    \  }}}|p|S )a;  Resolve the model a session should display without mutating persisted state.

    `GET /api/session` should stay side-effect free. If a stale persisted model
    needs normalization for the current provider configuration, return the
    effective model for the response payload only and leave disk state alone.
    r  NrI   r5  r@   rF  )rA   rL  rH  rI  _changeds        r   ,_resolve_effective_session_model_for_displayrT  ]  sU     Wgt44:N+R$)400, ,(OY ,n,r   c                 v    t          | dd           pd}t          |pd t          | dd                     \  }}}|S )Nr  rI   r5  rR  )rA   rL  _modelr  rS  s        r   5_resolve_effective_session_model_provider_for_displayrW  k  sM    Wgt44:N!H$)400" "FHh Or   c                    t          | pd                                          }|sdS 	 ddlm} ddlm}  |            }d}d}	 t          |t                    r|                    di           ni }t          |t                    rG|                    d          }	|	0	 t          |	          }
|
dk    r|
}n# t          t          f$ r Y nw xY wt          |t                    r|                    d          nd}t          |t                    r|}n# t          $ r Y nw xY w	  ||d||pd|	          pdS # t          $ r  ||d          pdcY S w xY w# t          $ r Y dS w xY w)
a
  Best-effort current context window for a session model.

    Persisted session context metadata is a snapshot from a prior model call.
    During session hydration/model switching, the current model metadata should
    be allowed to replace that stale snapshot.
    rI   r   )get_model_context_length
get_configNr  context_lengthcustom_providers)config_context_lengthr  r]  )r   r   agent.model_metadatarY  
api.configr[  r=   r>   r?   r  r  rh   listr[   )r  r  model_for_lookup_get_cl_get_config_for_cl_cfg_for_cl_cfg_ctx_len_load_cfg_custom_providers_load_model_cfg_load_raw_cfg_ctx_load_parsed_load_raw_cp_loads               r   )_resolve_context_length_for_session_modelrl  t  s    5;B''--// q#LLLLLL??????((** %)"	>HVZ>[>[ckoogr:::acO/400 $3$7$78H$I$I!$0'*+<'='='!++0<-%z2   BL[Z^B_B_i;??+=>>>eiL,-- :-9* 	 	 	D	
	67 &7!R!;      	6 	6 	67+R005A555	6    qqsy   E AD B6 5D 6C
D 	C

AD E 
DE DE "D6 6EE EE 
E"!E"r;  current_providerc                     | !t          |                                           nd }|t          |          nd }|r<t          |          \  }}|r|}n|t          |          }t	          ||          \  }}}||fS r;   )r   r   r(  r,  rF  )r  r;  rm  model_valuer  r  r<  rS  s           r   !_session_model_state_from_requestrp    s    
 ).(9#e**""$$$tK ) 	&&8999 
  	
#B;#O#O   	G(HH'45EFFH*Q+
 +
'Xx   r   r5   c                     | si S t                                          t          |                     }t          |t                    r|ni S r;   )rG  r?   r   r=   r>   )r5   r  s     r    _lookup_gateway_session_identityrr    sG     	13377JHHH!(D11988r9r   c                     | si S 	 t                      D ]}|                    d          | k    r|c S  n# t          $ r i cY S w xY wi S )Nr5   )get_cli_sessionsr?   r[   )r5   ri  s     r   _lookup_cli_session_metadataru    s~     	#%% 	 	Cww|$$
22


 3	    			Is   ,5 5 AArA   r%  c                    t          |                     d                    }t          |                    d          |                     d          |                     d                    }|r| d| S t          |                    d          |                     d          |                     d                    }t          |                    d          |                     d                    }t          |                    d          |                     d                    }t          |                    d	          |                     d	          |                     d
                    }g }|r|                    d|            |r|                    d|            |r|                    d|            |r|                    d|            |r| dd                    |          z   S |S )Nr5   r7  gateway_session_keyz|session_key:r9  origin_chat_idr:  r;  r<  origin_user_idz
chat_type:zchat_id:z
thread_id:zuser_id:|)rr  r?   r/  r   r  )	rA   r%  r  r7  r9  r:  r;  r<  identity_partss	            r   _messaging_session_identityr|    s	   /L0I0IJJH]##M"")** K
  988;888YI$%% G
 HLL55w{{;7O7OPPIHLL55w{{;7O7OPPIYI$%% G N 86966777 4222333 86966777 4222333 ;#((>":":::r   c                    t          |                     d          |                     d          |                     d          |                     d                    }|s|                     d          pd}t          |          S )Nr%  
source_tagr4   r6  source_label	messaging)r/  r?   r&  rA   rQ   s     r   _session_messaging_raw_sourcer    s{    
L!!L!!HJ	 C  9kk.))8[&s+++r   c                    t          |                     d                    }t          t          |                    d          |                     d          |                     d          |                    d          |                     d          |                     d          |                    d          |                     d                              S )Nr5   r7  rw  r9  rx  r:  )rr  r?   r  r/  )rA   r  s     r   _has_durable_messaging_identityr    s    /L0I0IJJH]##M"")**YI$%%[!!K  	 	 	 	 	r   c                     	 t          t          t          | d          pd                    S # t          t          f$ r Y dS w xY wNr   )r  r  r/  r  rh   r-  s    r   _numeric_countr    sS    5UA..3!44555z"   qq   +. AAactive_gateway_session_idsactive_gateway_sourcesc                    t          |           }t          |          sdS |r||vrdS t          |                     d                    }|r||v rdS t          |                     d                    t          v rdS t          |           sdS |                     d          rdS t          |                     d                    }t          |                     d                    }|dk    r|dk    rdS dS )	a  Hide stale Gateway-owned internal rows after an external chat moved on.

    Hermes Gateway keeps the external conversation identity in sessions.json.
    Compression/session-reset can leave old Agent state.db rows behind; those
    rows are implementation segments, not distinct conversations users chose.
    Only apply this aggressive hiding when Gateway is currently advertising an
    active session for the same messaging source. Without that source-of-truth
    file we keep the old fallback behavior.
    Fr5   
end_reasonTparent_session_idmessage_countactual_message_countr   )r  r)  r/  r?   _STALE_MESSAGING_END_REASONSr  r  )rA   r  r  r%  r   r  actual_counts          r   $_should_hide_stale_messaging_sessionr    s    /w77J%j11 u% ;Q)Q)Qu
gkk,//
0
0C
 s000u7;;|,,--1MMMt*733 t{{&'' t"7;;#?#?@@M!'++.D"E"EFFLla//t5r   c           	      x   | sdS t          | t                    st          | dd          n|                     d          dk    rdS t	          t          | t                    st          | dd          n|                     d          t          | t                    st          | dd          n|                     d          t          | t                    st          | dd          n|                     d          t          | t                    r|                     d	          nd          }t          |          S )
z?Return true for sessions backed by external messaging channels.Fsession_sourceNr  Tr%  r~  r4   r  )r=   r>   r@   r?   r/  r)  r  s     r   _is_messaging_session_recordr  B  s3    u9CGT9R9R	u*D	1	1	1X_XcXcdtXuXu  {F  	F  	Ft
4>w4M4Mlt,,,SZS^S^_kSlSl4>w4M4Mlt,,,SZS^S^_kSlSl0:7D0I0Id4(((w{{[cOdOd'1'4'@'@JN###d	 C &c***r   c                    t          | t                    sdS | D ]}t          |t                    r|                    d          dk    r1t          |                    d          t                    r|                    d          r dS |                    d          }t          |t                    rt	          d |D                       r dS dS )zHReturn true when returned messages can reconstruct their own tool cards.Frole	assistant
tool_callsTr   c              3   r   K   | ]2}t          |t                    o|                    d           dk    V  3dS )r  tool_useNr=   r>   r?   r   r   s     r   rx   z2_messages_include_tool_metadata.<locals>.<genexpr>]  sV       -
 -
 tT""Etxx'7'7:'E-
 -
 -
 -
 -
 -
r   )r=   ra  r>   r?   r   )messagesmsgr   s      r   _messages_include_tool_metadatar  S  s    h%% u 
 
#t$$ 	;(F(Fcggl++T22 	sww|7L7L 	44'')$$gt$$ 	 -
 -
-
 -
 -
 *
 *
 	 445r   	start_idxr  c                 N   t          | t                    r|dk    rg S ||z   }g }| D ]}}t          |t                    s|                    d          }t          |t                    st          |t
                    sX||cxk    r|k     rn h|                    |           ~|S )zHKeep session-level tool calls that point into a returned message window.r   assistant_msg_idx)r=   ra  r>   r?   r  r  r   )r  r  r  end_idxfiltered	tool_callassistant_idxs          r   _tool_calls_for_message_windowr  e  s    j$'' =A+=+=	-'GH ' '	)T** 	!&9::mT** 	*]C2P2P 	/////////OOI&&&Or   c                     t          | t                    sdS t          |                     d          pd                                                                          }t          |o|dk              S )a  Return true when a paginated window should include this transcript row.

    Tool result rows are rendered through their assistant anchor or hidden as raw
    tool output. A tail page containing only tool rows makes the frontend set
    ``S.messages`` to a non-empty array while the visible transcript and topbar
    count stay empty. Anchor small tail windows on the newest non-tool row so
    long sessions do not open to a blank chat with only transient metadata.
    Fr  rI   tool)r=   r>   r   r?   r   r   r  )r   r  s     r   (_message_counts_as_renderable_for_windowr  v  sh     gt$$ uw{{6""(b))//117799D'(((r   c           	      T   t          | pg           } |9t          dt          t          |          t	          |                               }nt	          |           }| d|         }|sg dfS |s|dfS t          dt          |                    }t	          |          }t          d||z
            }|||         }|rit          d |D                       sPt          |dz
  dd          D ];}	t          ||	                   r$|	dz   }t          d||z
            }|||         } n<||fS )a  Return a paginated message window plus its offset in ``messages``.

    The normal fast path is a raw tail window. If that window contains no
    renderable transcript rows because state.db appended hidden tool rows after
    the visible assistant tail, shift the window end back to the newest
    renderable row. This preserves the raw index cursor while avoiding the
    WebUI blank-transcript trap.
    Nr   r   c              3   4   K   | ]}t          |          V  d S r;   )r  )r   r  s     r   rx   z._message_window_for_display.<locals>.<genexpr>  s+      ZZCB3GGZZZZZZr   rY  )ra  r  r[  r  ro   r   ranger  )
r  	msg_limit
msg_before
before_idxr4   r`  r  r  windowr^  s
             r   _message_window_for_displayr    s\    HN##HCJX??@@

]]
kzk"F 1u qy3y>>""E&kkGAw''IIg%&F cZZSYZZZZZ 1b"-- 	 	C7sDD '7U?33		' 12	
 9r   c                    t          |pg           }t          t          | dg           pg           }|r|r||k    rg }t                      }t          t          |          t          |          z   d           D ]@}t	          |          }||v r|                    |           |                    |           A|S t          |          t          |          k    r|n|S |S )ac  Return the message coordinate space exposed by ``GET /api/session``.

    Messaging sessions can have a WebUI sidecar transcript plus messages from
    the Agent/CLI store. The frontend computes fork keep-counts against this
    merged display list, so branch/fork must slice the same list rather than
    the sidecar-only ``session.messages`` array.
    r  c                     t          |                     d          pd          t          |                     d          pd          t          |                     d          pd          fS )N	timestampr   r  rI   r   )r  r?   r   )r  s    r   r  z6_merged_session_messages_for_display.<locals>.<lambda>  s\    aeeK((-A..AEE&MM'R((AEE)$$*++Z r   r8  )ra  r@   r   r   _session_message_merge_keyr   r   ro   )rA   cli_messagessidecar_messagesmerged_messagesseen_message_keysr  r8  s          r   $_merged_session_messages_for_displayr    s    *++LGGZ<<BCC _ 	# 0L @ @ O #d<0048H3I3II P P    	, 	,
 155+++!%%c***&&s++++""#&'7#8#83|;L;L#L#LR^^r   c           	         t          | pg           } d}| D ]b}t          |t                    s	 t          |t	          |                    d          pd                    }L# t          t          f$ r Y _w xY wt          |           |dS )NrS  r  r   r  last_message_at)	ra  r=   r>   r  r  r?   r  rh   ro   )r  r  r  s      r   _message_summaryr    s    HN##HO  #t$$ 		!/59M9M9RQR3S3STTOO:& 	 	 	D	 ]]OOOs   2A""A65A6rk  c                    t          j        |           }d}d}|rt          t          |dd                    }|dk    r4t          |                                                    d                    }	 t          t          |dd          pd          }n# t          t          f$ r d}Y nw xY wt          |dd          ||dS t          | |	          }t          |                    d                    }	 t          |                    d
          pd          }n# t          t          f$ r d}Y nw xY w||k    r||k    r||dS ||dS )u  Return the cheap message summary used by metadata-only session loads.

    Threads ``profile=`` through to ``get_state_db_session_summary`` so
    background-thread reads land on the correct profile's state.db (per the
    cookie-bound profile selector — fixes the same TLS-vs-thread race the
    #2762 fix addressed for write paths).

    This intentionally does not full-read or merge transcripts.  If state.db has
    grown beyond the sidecar count, report that growth so active-session polling
    can refresh.  If state.db only contains restamped replay rows at or below the
    sidecar count, keep the sidecar metadata so polling does not loop forever on
    a false "newer transcript" signal.
    r   rS  _metadata_message_countNr  
updated_attruncation_watermarkr  rk  r  )
r_  load_metadata_onlyr  r@   compactr?   r  r  rh   get_state_db_session_summary)r   rk  sidecar_sessionsidecar_countsidecar_last_message_atstate_summarystate_countstate_last_message_ats           r   _metadata_only_message_summaryr    s    055OM! &w@Y[_'`'`aaA*?+B+B+D+D+H+H+Y+YZZM	*&+GO\ST,U,U,ZYZ&[&[##:& 	* 	* 	*&)###	*?$:DAAM "/#:   1gFFFM !2!2?!C!CDDK$ %m&7&78I&J&J&Oa P Pz" $ $ $ #$]""'<?V'V'V(4
 
 	

 '2  s$   4 B B+*B+8$D D32D3c                      sdS  fd}t                     rdS t           |d                    st           |d                    rdS t          t           |d                              }|dv rdS t          t           |d           |d	           |d
           |d           |d                              S )u  Return True when a sidecar/session row still needs CLI metadata.

    Legacy imported sidecars may predate the ``read_only`` field and therefore
    load with ``read_only=False``. They still persist ``is_cli_session`` and/or
    source metadata from import time, so those markers intentionally keep them
    on the CLI lookup path while ordinary WebUI-native sessions take the fast
    path.

    Supersedes the simpler is-cli-or-messaging gate from PR #1822 — the new
    gate is strictly more inclusive (also covers ``read_only=True`` sidecars,
    ``session_source`` markers, and source_tag/raw_source/platform metadata)
    so all sessions that previously took the slow path still do, plus a few
    more legacy shapes.
    Fc                 z    t          t                    r                    |           nt          | d           S r;   r<   )r   rA   s    r   _fieldz5_session_requires_cli_metadata_lookup.<locals>._field	  s7    $.w$=$=_w{{4   77TXZ^C_C__r   Tis_cli_session	read_onlyr  >   external-agentr  external_agentr~  r%  r4   r  r6  )r  r  r&  r/  )rA   r  r  s   `  r   %_session_requires_cli_metadata_lookupr  	  s     u` ` ` ` ` $G,, tFF#$$%% ff[.A.A)B)B t0VVDT=U=U1V1VWWNJJJt||x~z    r   c                     	 t          j        |           }t          |          rdS n# t          $ r Y nw xY wt          t	          |                     S )zCDetect messaging-backed sessions from WebUI metadata or Agent rows.T)r_  r`  r  r[   ru  )r   rA   s     r   _is_messaging_session_idr  )	  sg    ,s##'00 	4	   '(DS(I(IJJJs   #( 
55c           
          t          t          |                     d          |                     d          |                     d          |                     d          d          pd          pdS )Nr  r  
created_at
started_atr   rS  )r  r/  r?   rA   s    r   _session_sort_timestampr  4	  su    KK)**KK%%KK%%KK%%	
 	
 	    
r   c                    t          | t                    sdS t          |           rdS |                     d          sdS t	          |                     d          pd                                                                          }|t          v rdS t	          |                     d          pd                                                                          }|dv p|                    d          o| p|d	k    S )
zOReturn True for importable CLI sessions that are safe to classify for settings.FTr  r4   rI   title)rI   untitledclizcli sessionz sessionr  )	r=   r>   r	   r?   r   r   r   r   endswith)rA   r4   r  s      r   _is_cli_session_for_settingsr  @	  s    gt$$ u'"" t ;;'(( uX&&,"--3355;;==F"""uG$$*++113399;;E:: ennZ>X>X ?
%for   r   r1  cli_capc                     |dk    r| S g }d}| D ]2}t          |          r|dz  }||k    r|                    |           3|S )z?Keep only the most recent CLI-visible sessions after filtering.r   r   )r  r   )r1  r  keptcli_seenrA   s        r   _cap_recent_cli_sessionsr  W	  sj    !||DH  '00 	MH'!!GKr   
ui_sessioncli_metac                 ,   | s| S |st          |           S t          |           }d|d<   dD ]+}t          |                    |                    }|r|||<   ,|                    d          |d         |d<   |                    d          |d         |d<   |                    d          |d         |d<   |                    d          Tt          t	          |                    d                    t	          |                    d                              |d<   nh|                    d	          St          t	          |                    d                    t	          |                    d	                              |d<   |                    d
          r(|                    d
          }|r|dk    r|d
         |d
<   |                    d          r9|                    d          r|                    d          dk    r|d         |d<   |S )zMerge source-of-truth CLI metadata into a sidebar session row.

    Preserve UI-owned state (archived/pinned) while replacing metadata that can
    legitimately drift in WebUI snapshots.
    Tr  )r~  r%  r  r  r<  r9  r;  r:  r7  r6  r  r  r  _lineage_root_id_lineage_tip_id_compression_segment_countr  Nr  r  r  r  r  Untitledr  r  )r>   r/  r?   r  r  )r  r  mergedr8  r-  current_titles         r   _merge_cli_sidebar_metadatar  f	  s+       J*F#F    $ HLL--.. 	 F3K||L!!-'5|||L!!-'5|||%&&2$,->$? !||O$$0"%6::o66778<<8899#
 #
 
,	-	-	9"%6::o66778<<(>??@@#
 #

 ||G 0

7++ 	0 ; ;&w/F7O||G 0zz'"" 	0fjj&9&9Y&F&F&w/F7OMr   c                 b    t          |           }t          |          sd S t          | |          S r;   )r  r)  r|  r  s     r   _messaging_source_keyr  	  s4    
'
0
0C%c** t&w444r    show_previous_messaging_sessionsr  c                   |rt          | t          d          S t                      }d |                                D             }d | D             }||z  fd|                                D             }d |D             }t                      }i }g }| D ]}	t          |	          }
|
s|                    |	           )t          |	|          r;|
|v rR|	                    |
           |
                    |
          }| t          |	          t          |          k    r|	||
<   |	                    |
           |	||
<   |                    |                                           |                    t          d           |S )z@Keep only the newest sidebar row per messaging session identity.Tr8  reversec                 0    h | ]}|t          |          S r   r  )r   r   s     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>	  s$    !U!U!UsQT!U#c((!U!U!Ur   c                 |    h | ]9}t          |t                    t          |                    d                     :S r5   )r=   r>   r/  r?   )r   rA   s     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>	  sL       gt$$GKK--..  r   c           
          h | ]a\  }}|v 	t          |t                    t          t          |                    d           |                    d                              bS )r%  r6  )r=   r>   r&  r/  r?   )r   r   meta"visible_active_gateway_session_idss      r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>	  sm       C444D$9O9O4 	$K0F0FQ[H\H\$]$]^^444r   c                 0    h | ]}t          |          |S r   )r)  )r   r4   s     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>	  s'    pppMghnMoMopfpppr   )r   r  rG  keysr  r   r  r   r  r   r?   r}   r,  sort)r1  r  gateway_metadatar  session_idsr  kept_sourcesbest_by_sourcer  rA   r8  currentr  s               @r   )_keep_latest_messaging_session_per_sourcer  	  s    ( Kh$;TJJJJ9;;!U!U6F6K6K6M6M!U!U!U   K
 *Dk)Q&   )//11  
 qp3Ippp UUL&(ND & &#G,, 	KK   /9[]stt 	,S!!!$((--G"9'"B"BE\]dEeEe"e"e&-s#%sKK%%''(((II)4I888Kr   )r_  r   new_sessionall_sessions
title_from_write_session_indexSESSION_INDEX_FILE_active_state_db_pathload_projectssave_projectsimport_cli_sessionrt  get_cli_session_messagesget_state_db_session_messagesr  "merge_session_messages_append_onlyr  prune_session_from_indexensure_cron_projectis_cron_session)load_workspacessave_workspacesget_last_workspaceset_last_workspacelist_dirdir_signaturelist_workspace_suggestionsread_file_contentsafe_resolve_wsresolve_trusted_workspacevalidate_workspace_to_add_is_blocked_system_path_strip_surrounding_quotes_workspace_blocked_roots)handle_uploadhandle_upload_extracthandle_transcribe)_sse_run_agent_streamingcancel_streamrI  )find_run_summaryread_run_eventsstale_interrupted_event)get_providersget_provider_quotaget_provider_cost_historyset_provider_keyremove_provider_key)apply_onboarding_setupget_onboarding_statuscomplete_onboardingprobe_provider_endpoint)cancel_onboarding_oauth_flowpoll_onboarding_oauth_flowstart_onboarding_oauth_flow)submit_pendingapprove_sessionapprove_permanentsave_permanent_allowlistis_approved_pending_lock_permanent_approved_gateway_queuesresolve_gateway_approvalenable_session_yolodisable_session_yolois_session_yolo_enabledc                      d S r;   r   aks     r   r  r  ,
      $ r   c                      d S r;   r   rL  s     r   r  r  -
  s    d r   c                      d S r;   r   rL  s     r   r  r  .
  s     r   c                      d S r;   r   rL  s     r   r  r  /
  s    t r   c                      dS NTr   rL  s     r   r  r  0
  s    $ r   c                      dS r  r   rL  s     r   r  r  1
  s    q r   c                      d S r;   r   rL  s     r   r  r  2
  rO  r   c                      d S r;   r   rL  s     r   r  r  3
  s    4 r   c                      dS r  r   rL  s     r   r  r  4
  s    e r   _approval_sse_subscribersc                     t          j        d          }t          5  t                              | g                               |           ddd           n# 1 swxY w Y   |S )zBRegister an SSE subscriber for approval events on a given session.   r  N)r  r  rD  rY  rm  r   )r5   qs     r   _approval_sse_subscriber]  ?
  s    BA	 G G!,,Z<<CCAFFFG G G G G G G G G G G G G G GHs   /AAAr\  c                     t           5  t                              |           }|r6||v r2|                    |           |st                              | d           ddd           dS # 1 swxY w Y   dS )zRemove an SSE subscriber.N)rD  rY  r?   removerP  )r5   r\  subss      r   _approval_sse_unsubscribera  G
  s    	 @ @(,,Z88 	@AIIKKNNN @)--j$???@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @s   AA((A,/A,headtotalc                     |rt          |          nd|d}t                              | d          }|D ]-}	 |                    |           # t          j        $ r Y *w xY wdS )u  Push an approval event to all SSE subscribers for a session.

    CALLER MUST HOLD `_lock`. Snapshots the subscriber list under the held
    lock and then calls `q.put_nowait()` on each (which is itself thread-safe).

    `head` is the approval entry currently at the head of the queue (the one
    the UI should display) — NOT the just-appended entry. With multiple
    parallel approvals (#527), the just-appended entry is at the TAIL, but
    `/api/approval/pending` always returns the HEAD, so SSE must match.

    `total` is the total number of pending approvals.

    Pass `head=None` and `total=0` when the queue has just been emptied (e.g.
    `_handle_approval_respond` popped the last entry) so the client knows to
    hide its approval card.
    Npendingpending_countr   )r>   rY  r?   
put_nowaitr  Full)r5   rb  rc  r   r`  r\  s         r   _approval_sse_notify_lockedrj  Q
  s    " )-6$t***$OOG$((R88D  	LL!!!!z 	 	 	D	 s   AAAc                 h    t           5  t          | ||           ddd           dS # 1 swxY w Y   dS )a  Convenience wrapper that takes `_lock` itself.

    Use only from contexts that don't already hold `_lock`. Production call
    sites (submit_pending, _handle_approval_respond) MUST hold the lock and
    call `_approval_sse_notify_locked` directly to avoid a notify-ordering
    race where a later append's notify can fire before an earlier append's
    notify (resulting in stale `pending_count`).
    N)rD  rj  )r5   rb  rc  s      r   _approval_sse_notifyrl  k
  s     
 = =#Je<<<= = = = = = = = = = = = = = = = = =s   '++r7  approvalc                    t          |          }|                    dt          j                    j                   t
          5  t          j        | g           }t          |t                    s|gt          | <   t          |          }|	                    |           t          |          }|d         }t          | ||           ddd           dS # 1 swxY w Y   dS )a  Append a pending approval to the per-session queue.

    Wraps the agent's submit_pending to:
    - Add a stable approval_id (uuid4 hex) so the respond endpoint can target
      a specific entry even when multiple approvals are queued simultaneously.
    - Change the storage from a single overwriting dict value to a list, so
      parallel tool calls each get their own approval slot (fixes #527).
    - Notify any connected SSE subscribers immediately.
    approval_idr   N)r>   rm  uuiduuid4hexrD  rC  r=   ra  r   ro   rj  )r7  rm  r1  
queue_listrc  rb  s         r   r>  r>  x
  s    NNE	]DJLL$4555	 > >(b99
*d++ 	/%/LH[!!+.J%   J!} 	$Ku===> > > > > > > > > > > > > > > > > >s   B CCC)r>  get_pendingresolve_clarifyresolve_clarify_by_idsse_subscribesse_unsubscribec                      d S r;   r   rL  s     r   r  r  
  s    T r   c                      d S r;   r   rL  s     r   r  r  
  rO  r   c                      dS r  r   rL  s     r   r  r  
  s    a r   c                      dS r  r   rL  s     r   r  r  
  s    E r   enzSign inzEnter your password to continuePasswordInvalid passwordzConnection failed)langr  subtitleplaceholderbtn
invalid_pwconn_failedzfr-FRzSe connecterz(Entrez votre mot de passe pour continuerzMot de passezMot de passe invalideu   Échec de la connexionzes-ESu   Iniciar sesiónu'   Introduce tu contraseña para continuaru   ContraseñaEntraru   Contraseña inválidau   Error de conexiónzde-DEAnmeldenz+Geben Sie Ihr Passwort ein, um fortzufahrenPasswortu   Ungültiges PasswortzVerbindung fehlgeschlagenzru-RUu
   Войтиu<   Введите пароль, чтобы продолжитьu   Парольu   Неверный парольu,   Не удалось подключитьсяzzh-CNu   登录u   输入密码继续使用u   密码u   密码错误u   连接失败zzh-TWu   輸入密碼繼續使用u   密碼u   密碼錯誤u   連接失敗zit-ITAccediz$Inserisci la password per continuarezPassword non validazConnessione fallitazja-JPu   サインインu$   パスワードを入力して続行u   パスワードu   パスワードが無効ですu   接続失敗zpt-BRzDigite sua senha para continuarSenhau   Senha inválidau   Falha na conexãozko-KRu	   로그인u/   계속하려면 비밀번호를 입력하세요u   비밀번호u)   비밀번호가 올바르지 않습니다u   연결 실패ztr-TRu
   Oturum açu"   Devam etmek için şifrenizi girinu   Şifreu   Geçersiz şifreu   Bağlantı başarısız)r}  fresr  ruzhzh-Hantitjaptkotrraw_langc                    | sdS t          |                                           }|sdS |t          v r|S |                    dd          }|                                }t          D ]}|                                |k    r|c S |dk    s?|                    d          s*|                    d          s|                    d          rdS |                    d          s?|                    d	          s*|                    d
          s|                    d          rdt          v rdndS |                    dd          d         }t          D ]}|                                |k    r|c S dS )z7Resolve settings.language to a known _LOGIN_LOCALE key.r}  r   r#  r  zzh-cnzzh-sgzzh-hanszzh-twzzh-hkzzh-mozzh-hantr  r   r   )r   r   _LOGIN_LOCALEr%  r   r   r   )r  r  r  r   r8  bases         r   _resolve_login_locale_keyr    s    tx==  D t}c3''JE   99;;%JJJ   }}((11}U5E5Eg5N5N}RWRbRbclRmRm}t   AE$4$4W$=$= AAQAQRYAZAZ A^c^n^nox^y^y A%66yyD@ ;;sAq!D  99;;$JJJ 4r   u	  <!doctype html>
<html lang="{{LANG}}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{BOT_NAME}} — {{LOGIN_TITLE}}</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#1a1a2e;color:#e8e8f0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  height:100vh;display:flex;align-items:center;justify-content:center}
.card{background:#16213e;border:1px solid rgba(255,255,255,.08);border-radius:16px;padding:36px 32px;
  width:320px;text-align:center;box-shadow:0 8px 32px rgba(0,0,0,.3)}
.logo{width:48px;height:48px;border-radius:12px;background:linear-gradient(145deg,#e8a030,#e94560);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:20px;color:#fff;
  margin:0 auto 12px;box-shadow:0 2px 12px rgba(233,69,96,.3)}
h1{font-size:18px;font-weight:600;margin-bottom:4px}
.sub{font-size:12px;color:#8888aa;margin-bottom:24px}
input{width:100%;padding:10px 14px;border-radius:10px;border:1px solid rgba(255,255,255,.1);
  background:rgba(255,255,255,.04);color:#e8e8f0;font-size:14px;outline:none;margin-bottom:14px;
  transition:border-color .15s}
input:focus{border-color:rgba(124,185,255,.5);box-shadow:0 0 0 3px rgba(124,185,255,.1)}
button{width:100%;padding:10px;border-radius:10px;border:none;background:rgba(124,185,255,.15);
  border:1px solid rgba(124,185,255,.3);color:#7cb9ff;font-size:14px;font-weight:600;cursor:pointer;
  transition:all .15s}
button:hover{background:rgba(124,185,255,.25)}
.passkey-login{margin-top:10px;background:rgba(255,255,255,.04);border-color:rgba(232,160,48,.35);color:#e8a030}
.err{color:#e94560;font-size:12px;margin-top:10px;display:none}
</style></head><body>
<div class="card">
  <div class="logo">{{BOT_NAME_INITIAL}}</div>
  <h1>{{BOT_NAME}}</h1>
  <p class="sub">{{LOGIN_SUBTITLE}}</p>
  <form id="login-form" data-invalid-pw="{{LOGIN_INVALID_PW}}" data-conn-failed="{{LOGIN_CONN_FAILED}}">
    <input type="password" id="pw" placeholder="{{LOGIN_PLACEHOLDER}}" autofocus>
    <button type="submit">{{LOGIN_BTN}}</button>
    <button type="button" id="passkey-login" class="passkey-login" style="display:none">Sign in with passkey</button>
  </form>
  <div class="err" id="err"></div>
</div>
<!-- Keep login.js relative so subpath mounts load it under the current scope. -->
<script src="static/login.js?v={{WEBUI_VERSION}}"></script>
</body></html>z	agent.logz
errors.logzgateway.log)agenterrorsgateway>   r)   r       i  @ c                     	 t          t          | pd                                                    }n# t          t          f$ r
 t
          cY S w xY w|t          v r|nt
          S r#  )r  r   r   r  rh   _LOG_DEFAULT_TAIL_LOG_TAIL_VALUES)raw_tailtails     r   _normalize_logs_tailr  s  sp    !3x~2&&,,..//z" ! ! !    !+++441BBs   03 AAc                 8   t          |j                  }|                    ddg          d         pd                                                                }t
                              |          }|st          | dd          S t          |                    ddg          d                   }	 dd	lm	} t           |                                                      }nd# t          $ rW t          t          j                            d
          pt          j                    dz                                            }Y nw xY w|dz  }||z  }		 |	                    d          j        |                    d          k    rt          | dd          S |	                                r|	                                st)          | ||g dddd| dd          S |	                                }
t-          |
j                  }t1          |t2                    }|	                    d          5 }||k    r|                    ||z
             |                    |          }ddd           n# 1 swxY w Y   |                    dd          }|                                | d         }t)          | |||||k    ||
j        dd          S # t          $ rD}t@          !                    d|           t          | tE          |          d          cY d}~S d}~ww xY w)zCReturn a bounded tail window for an active-profile Hermes log file.r  r  r   zUnknown log file  r5  r  NrT   rX   rY   logsF)strictzInvalid log filezLog file for z not found yet.)r  r  lines	truncatedtotal_bytesr!   r   rbr   r%  r  rI   z&Failed to read whitelisted log file %sr  )#r   rN   r?   r   r   _LOG_FILE_WHITELISTr&  r  rZ   rU   r   r`   r[   r]   environr_   re   r   rz   r   r(  r=  r  st_sizer[  _LOG_MAX_BYTESopenseekr  r  
splitlinesr?  r   r  r+  )r6  r7  rN   file_keyfilenamer  rU   r2  log_dirlog_pathrA  r  
read_bytesfhrQ   r.  r  r  s                     r   _handle_logsr  {  s   V\""E		&7),,Q/:7AACCIIKKH"&&x00H <7.s;;;;		&4& 9 9! <==Dd777777113344??AA d d d2:>>-88UTY[[9=TVVaaccd F"G!H#> 5))0GOO5O4Q4QQQw 23????   		(8(8(:(: 		W " AAAA     ]]__"*oon55
]]4   	&BZ''j0111''*%%C	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& zz')z44!!4%&&)$z1&[
 
   	  > > >A8LLL7OC00=========>se   1/C! !AEEAK AK AK +4I+K +I//K 2I/3AK 
L9LLLz_https://hermes-agent.nousresearch.com/docs/user-guide/skills/bundled/research/research-llm-wiki)entitiesconceptscomparisonsqueriesc            
      ,   	 ddl m}  t           |                                                       S # t          $ rX t          t          j        dt          t          j                    dz                                                                cY S w xY w)Nr   rT   rX   rY   )	rZ   rU   r   r`   r[   r]   r^   r   r_   rT   s    r   _llm_wiki_active_hermes_homer    s    Y777777**,,--88::: Y Y YBImSy1H-I-IJJKKVVXXXXXYs   .1 ABBr2  c                 $   | dz  }|                                 r|                                sd S 	 |                    dd                                          D ]}|                                }|r|                    d          sd|vr2|                    dd          \  }}|                                dk    rd|                                                    d	                              d
          }|pd c S n# t          $ r Y d S w xY wd S )Nz.envr   r%  r   r  r   =r   	WIKI_PATH"')rz   r   r   r  r   r   r   r[   )r2  env_pathr   strippedr8  r-  s         r   _llm_wiki_env_file_pathr    s4   V#H?? H$4$4$6$6 t&&	&JJUUWW 	! 	!Dzz||H x22377 3h;N;N!Q//JCyy{{k))KKMM'',,22377E=D   	!    tt4s   CC? ?
DDconfig
dotted_keyc                 H   t          | t                    sd S || v r7|                     |          r"t          |                     |                    S | }|                    d          D ]&}t          |t                    r||vr d S ||         }'|rt          |          nd S )Nr$  )r=   r>   r?   r   r   )r  r  curr   s       r   _llm_wiki_get_config_path_valuer    s    fd## tV

: 6 66::j))***
C  %%  #t$$ 	C44$i$3s888$r   c                      	 ddl m}   |             }n# t          $ r Y d S w xY wt          |d          pt          |d          S )Nr   rZ  skills.config.wiki.pathz	wiki.path)r`  r[  r[   r  )_get_cfgcfgs     r   _llm_wiki_config_pathr    so    555555hjj   tt 	(-FGG 	=*3<<s    
!!i'  c              #      K   | ]D}t          t          |                                                                                    V  Ed S r;   )r   r   r`   re   rv   s     r   rx   rx     sY       & &,-CQ$$&&''& & & & & &r   )r   z/etcz/usrz/varz/optz/sysz/procc                  D   t                      } t          j        d          pt          |           }|rdnd}t	          |          }|st                      }|rd}d}|sd}t          t          j                            |                    	                                ||fS )Nr  rC   r  Tz~/wiki)
r  r]   r^   r  r  r  r   r    
expandvarsr`   )r2  rQ   r4   
configureds       r   _llm_wiki_resolve_pathr    s    .00K
)K
 
 
H$;K$H$HC.[[YFcJ #%% 	.FJ ""3''((3355vzIIr   r  c                     | sd S 	 ddl m }m} |                    | |j                                                                      dd          S # t          $ r Y d S w xY w)Nr   )datetimetimezone)tz+00:00Z)r  r  fromtimestamputc	isoformatr%  r[   )r  r  r  s      r   _llm_wiki_safe_isor    s     t////////%%bX\%::DDFFNNxY\]]]   tts   A	A 
AArootc                    |                                  r|                                 sdS 	 t          |                                           t          v rdS n# t
          $ r Y dS w xY wd}d}|                     d          D ]o}|dz  }|t          k    r n\	 |                                r6t          d |
                    |           j        D                       s|dz  }`# t
          $ r Y lw xY w|S )Nr   r   r   c              3   @   K   | ]}|                     d           V  dS r$  Nr   r  s     r   rx   z(_llm_wiki_count_files.<locals>.<genexpr>   s.      )h)h4$//#*>*>)h)h)h)h)h)hr   )rz   r   r   re   _LLM_WIKI_FORBIDDEN_ROOTSr[   r   _LLM_WIKI_MAX_FILESr   r   rf   rn   )r  r   iterateditems       r   _llm_wiki_count_filesr    s$   ;;==  qt||~~";;;1 <   qqEH

3  A)))E	||~~ c)h)h4K[K[\`KaKaKg)h)h)h&h&h 
 	 	 	H	Ls$   (A 
A%$A%A
C!!
C.-C.	wiki_pathc                 0   g }	 t          |                                           t          v r|S n# t          $ r |cY S w xY wd}t          D ]}| |z  }|                                r|                                s0|                    d          D ]}|dz  }|t          k    r|c c S 	 |	                    |          }|
                                r3t          d |j        D                       s|                    |           v# t          $ r Y w xY w|S )Nr   r   r   c              3   @   K   | ]}|                     d           V  dS r  r  r  s     r   rx   z'_llm_wiki_page_files.<locals>.<genexpr>:  s.      -Y-Ytdooc.B.B-Y-Y-Y-Y-Y-Yr   )r   re   r  r[   _LLM_WIKI_PAGE_DIRSrz   r   r   r  rf   r   r   rn   r   )r  pagesr  dirnamesectionr  rels          r   _llm_wiki_page_filesr  '  sc   Ey  ""##'@@@L A   H&  g%~~ 	w~~'7'7 	MM&)) 		 		DMH---&&w//<<>> '#-Y-Ysy-Y-Y-Y*Y*Y 'LL&&&   		 Ls   )/ >>(AD
DDc                     	 t                      \  } }}dddddddd||ddt          d}|                                 s|S |                                 sd|d<   |S t	          |           }d	 | d
z  | dz  | dz  fD             }|                    |           d}|D ]A}	 |                                j        }n# t          $ r Y )w xY w||nt          ||          }B|
                    dd|rdndt          |          t          |          t          | dz            t          |          d           |S # t          $ r2}	ddddddddddddt          t          |	          j        dcY d}	~	S d}	~	ww xY w)zIReturn private-safe LLM Wiki status metadata without reading page bodies.Fmissingr   NzoHermes Agent exposes WIKI_PATH/wiki.path for location, but no stable on/off config flag is currently available.)r   enabledr  entry_count
page_countraw_source_countlast_updatedlast_writerpath_configuredpath_sourcetoggle_availabletoggle_reasondocs_urlnot_directoryr  c                 b    g | ],}|                                 |                                *|-S r   )rz   r   rv   s     r   r{   z*_build_llm_wiki_status.<locals>.<listcomp>[  sd      J  J  Janonvnvnxnx  J}~  ~G  ~G  ~I  ~I  J  J  J  Jr   z	SCHEMA.mdzindex.mdzlog.mdTreadyemptyrQ   )r   r  r  r  r  r  r  r   r  z)Unable to inspect LLM Wiki status safely.)r   r  r  r  r  r  r  r  r  r   r  r  r  r   )r  _LLM_WIKI_DOCS_URLrz   r   r  r}   r=  r?  r[   r  updatero   r  r  r  r  )
r  r   r  r  
page_filesstatus_fileslatestr  r!   r  s
             r   _build_llm_wiki_statusr  A  s-   <
2H2J2J/	; ! .& % O*
 
 !! 	K!! 	,DNK))44
 J  JI$;Y=SU^aiUi#j  J  J  JJ'''  	E 	ED		,   $nUU#fe2D2DFF!+8ggz??j// 5i%6G H H.v66
 
 	 	 	  
 
 
 ! $$ %H*#YY'
 
 	
 	
 	
 	
 	
 	

sN   <D6 D6 AD6 B76D6 7
CD6 CA1D6 6
E2 'E-'E2-E2c                 >    t          | t                                 dS rT  )r(  r  )r6  r7  s     r   _handle_llm_wiki_statusr    s    g%''(((4r   c                   012 ddl }ddl}t          |j                  }	 t	          t          t          |                    ddg          d                   d          d          }n# t          t          f$ r d}Y nw xY w|                                }|
                    |          }|                    |j        |j        |j        ddd|j        |j        |j        f	          }d}	||dz
  |	z  z
  }
|
}d	t          fd
}d	t$          fd}dt&          d	t$          fd}g }t(          dz  }|                                r<	 t-          j        |                    d                    }n# t2          $ r g }Y nw xY wg }|D ]\}|                    dd          pd}|                    dd          pd}t          ||          |k     rG|                    |           ]t7          |          }d}d}d}d}i }i }|                                0|                                2|D ]} ||                    d                    } ||                    d                    } ||                    d                    }| ||                    d                    z  }||z  }||z  }||z  }|                    d          pd} |                    | ddddd          }!|!dxx         dz  cc<   |!dxx         |z  cc<   |!dxx         |z  cc<   |!dxx         |z  cc<    ||          }"|"r	 |
                    |"          }#|                    d|#          }$|                    |$ddddd          }%|%dxx         |z  cc<   |%dxx         |z  cc<   |%dxx         dz  cc<   |%dxx         |z  cc<   0|#j        xx         dz  cc<   2|#j        xx         dz  cc<   # t2          $ r Y w xY w||z   }&g }'|                                 D ]\  } }(|(d         |(d         z   })tC          |(d         d          }*|'                    | |(d         |(d         |(d         |)|*|r(t          tC          |(d         |z  d z                      nd|&r"t          tC          |)|&z  d z                      nd|r"t          tC          |*|z  d z                      ndd!	           |'"                    d" #           g }+tG          |          D ]},|
|,|	z  z   }-|                    d|
                    |-                    }$|                    |$ddddd          }!|+                    |$|!d         |!d         |!d         tC          |!d         d          d$           g d%101fd&tG          d'          D             }.2fd(tG          d)          D             }/tI          | ||||||&tC          |d          |'|+|.|/d*          S )+z5Return usage analytics from local WebUI session data.r   Ndays30r   m  r,   iQ rF   c                     	 t          t          t          | pd                    d          S # t          t          f$ r Y dS w xY wr  )r  r  r  r  rh   r  s    r   _safe_usage_intz)_handle_insights.<locals>._safe_usage_int  sR    	s5!,,--q111:& 	 	 	11	r  c                     | dS 	 t          | t                    r@|                                                     dd                              dd          } | sdS t	          t          |           d          S # t          t          f$ r Y dS w xY w)NrS  $rI   r  )r=   r   r   r%  r  r  r  rh   r  s    r   _safe_cost_floatz*_handle_insights.<locals>._safe_cost_float  s    =3	%%% --c266>>sBGG 3uU||S))):& 	 	 	33	s   AA8 A8 8BBrA   c                     |                      d|                      dd                    p|                      dd          pdS )Nr  r  r   r   r  s    r   _session_usage_tsz+_handle_insights.<locals>._session_usage_ts  s?    {{<\1)E)EFFk'++VbdeJfJfkjkkr   z_index.jsonr   r   r  r  rS  input_tokensoutput_tokensestimated_costr  r  r  )r1  r  r  costr1  r  z%Y-%m-%d)r  r  r1  r     r)   )	r  r1  r  r  total_tokensr  session_sharetoken_share
cost_sharec                 4    | d          | d          | d         fS )Nr  r1  r  r   )rs    r   r  z"_handle_insights.<locals>.<lambda>	  s    !F)a
m^QwZ(P r   r  )dater  r  r1  r  )MonTueWedThuFriSatSunc                 N    g | ]!}|                              |d           d"S )r   )dayr1  r   )r   idow_activity
dow_labelss     r   r{   z$_handle_insights.<locals>.<listcomp>  s5    ]]]q
1<3C3CAq3I3IJJ]]]r      c                 B    g | ]}|                     |d           dS )r   )hourr1  r   )r   r  hod_activitys     r   r{   z$_handle_insights.<locals>.<listcomp>"  s1    SSSA(8(8A(>(>??SSSr      )period_daystotal_sessionstotal_messagestotal_input_tokenstotal_output_tokensr   
total_costr2  daily_tokensactivity_by_dayactivity_by_hour)%collectionsrK  r   rN   r[  r  r  r?   rh   r  	localtimemktimetm_yeartm_montm_mdaytm_wdaytm_ydaytm_isdstr  r>   r  rz   r  r  r   r[   r   ro   Counterrm  strftimetm_hourr  roundr  r  r(  )3r6  r7  rA  _timerN   r  r  todaytoday_midnightday_secsfirst_day_tsr  r  r  r  sessions_dataidx_pathr^  r1  createdupdatedr9  r:  r;  r<  r=  model_statsr>  r   r  r  
cost_valuer  bucketr  dtday_keydaily_bucketr   models_breakdownstatsrow_total_tokensrow_costdaily_seriesr0  day_tsdow_datahod_datar1  r2  r6  s3                                                   @@@r   _handle_insightsre    s   V\""E3s599VdV44Q788!<<cBB	"    **,,COOC  E\\5=%,qRSUVX]Xeglgtv{  wE  #F  G  GNH!dQh(%:;LF#    
5 
 
 
 
l4 lE l l l l M]*H 	*X///AABBCC 	 	 	CCC	  $ $))L!,,1))L!,,1w  6))U#### ''NNJ#%K$&L&&((L&&((L ( (&quu^'<'<=='o(>(>??%%aee,<&=&=>>
//!%%*@*@AAAl*},j 
g+)''	0
 0
   	za~,.=0v*$ q!! 	__R((..R88+66w$%%& !	A A     ^,,,<,,,_--->---Z(((A-(((V$$$
2$$$RZ(((A-(((RZ(((A-((((   !	( &(;;L#))++  u 053IIv**j)!.1"?3,WelSj(9N(Jc'Q!R!RSSSklR^e3u&6&E%LMMNNNdeGQX#eX
%:c$ABBCCCWX
!
 
!
 
	 
	 
	 
	 PPQQQL4[[  X...U__V-D-DEE!!'	,
 ,
   	">2#O4z*&.!,,
 
 	 	 	 	 CBBJ]]]]]TYZ[T\T\]]]H TSSSrSSSHW((02$J**"$#$    s7   AA( (A>=A>>(E' 'E65E6,B0O
O,+O,c           
          t          | dd           }t          t          |dd          pd          t          t          t          |dd          pd          d          dS )Nserveraccept_loop_requests_totalr   accept_loop_last_request_atrS  rm   )requests_totallast_request_at)r@   r  rM  r  )r6  rg  s     r   _accept_loop_healthrl  6  sj    Wh--Fgf.JANNSRSTT wv7TVY'Z'Z'a^a!b!bdeff  r         ?r  c                 8   t          j                     }t          j        |           }t          t          j                     |z
  dz  d          }|sd| |dS 	 dt	          t
                    |dt          j                     S # t          j                     w xY w)Nr  r  r   blocked)r  r  msr  )r  active_streamsrp  )rK  r  acquirerM  ro   r  release)r  t0acquired
elapsed_mss       r   _streams_lock_healthrw  >  s    	B#O<<<H	b(D0!44J 
.
 
 	

!'ll
 
 	s   B Bc                     g } d}d}t           5  t          t          j                              }ddd           n# 1 swxY w Y   |D ]\  }}i }t	          |dd          }t          |          r5	  |            }t          |t                    r|}n# t          $ r i }Y nw xY wt          |
                    d          pd          }	t          |
                    d          pd          }
||	z  }||
z  }|                     t          |          |	|
d           |                     d            t          |           ||| d	S )
up  Return non-sensitive SSE stream diagnostics for health/deep status.

    The WebUI chat path can feel slow or stuck when streams are alive but no
    browser is attached, or when many events are buffering offline. This helper
    exposes counts only — stream ids plus subscriber/buffer sizes — and avoids
    event payloads, prompts, tool arguments, or paths.
    r   Ndiagnostic_snapshotsubscriber_countoffline_buffered_events)r6   rz  r{  c                     | d         S )Nr6   r   r  s    r   r  z-_stream_runtime_diagnostics.<locals>.<lambda>r  s    ${"3 r   r  )rq  total_subscriberstotal_offline_buffered_eventsstreams)r  ra  r  r  r@   callabler=   r>   r[   r  r?   r   r   r  ro   )r  r~  r  r  r6   streamsnapshotry  raw_snapshotrz  r{  s              r   _stream_runtime_diagnosticsr  R  s    G$%!	 & &W]__%%& & & & & & & & & & & & & & &"  	6%f.CTJJ'(( 	2244lD11 ,+H   x||,>??D1EE"%hll3L&M&M&RQR"S"S--%)@@%Y 0'>
 
 	 	 	 	
 LL33L444g,,.)F	  s   !;??0!BB! B!c            	         ddl m}  t          j                    }| j        5  g }| j        pi                                 D ]\  }}t          |pi           }|                    d          }	 t          d|t          |          z
            }n# t          $ r d}Y nw xY w|                    d|           t          |d          |d<   |                    |           | j        }ddd           n# 1 swxY w Y   |                    d	 
           t!          |          ||d}	|r |d                             dd          |	d<   n3|r1t          t          d|t          |          z
            d          |	d<   |	S )zBReturn active worker-run state independent of SSE stream presence.r   )r  r  rS  r6   r   age_secondsNc                 J    t          |                     d          pd          S )Nr  rS  )r  r?   r}  s    r   r  z'_run_lifecycle_health.<locals>.<lambda>  s    uTXXl%;%;%BsCC r   r  )active_runsrunslast_run_finished_atoldest_run_age_secondsidle_seconds_since_last_run)apir  rK  ACTIVE_RUNS_LOCKACTIVE_RUNSr  r>   r?   r  r  r[   rm  rM  r   LAST_RUN_FINISHED_ATr  ro   )
_live_configr  r  r6   rQ   r  r  agelast_finishedr   s
             r   _run_lifecycle_healthr  {  s    +*****
)++C		& : :+7=2DDFF 		 		NIs	r??D,//J#sU:%6%6677   OOK333"'Q--DKK$9: : : : : : : : : : : : : : : 	IICCIDDD4yy - G
  `,0GKKs,K,K())	 `16s3eMFZFZ@Z7[7[]^1_1_-.Ns7   A	C0+ BC0BC0BA	C00C47C4stream_checkc                    i }| | nt                      |d<   ddit                      |d<   |d                             d          dk    r|dfS t          j                    }	 t	                      }dt          |          t          t          j                    |z
  dz  d          d	|d
<   nW# t          $ rJ}dt          |          j	        t          t          j                    |z
  dz  d          d|d
<   Y d}~nd}~ww xY wt          j                    }	 t          d          }dt          |          t          t          j                    |z
  dz  d          d	|d<   nW# t          $ rJ}dt          |          j	        t          t          j                    |z
  dz  d          d|d<   Y d}~nd}~ww xY wt          j                    }	 t                      }|                                s.dt          t          j                    |z
  dz  d          d|d<   nt          t          j        t!          |                              5 }|                    d                                           ddd           n# 1 swxY w Y   dt          t          j                    |z
  dz  d          d|d<   nW# t          $ rJ}dt          |          j	        t          t          j                    |z
  dz  d          d|d<   Y d}~nd}~ww xY wt'          d |                                D                       }||fS )aR  Run cheap probes that exercise the state paths used by the UI shell.

    Plain /health intentionally stays tiny. /health?deep=1 is for supervisors
    and watchdogs that need to know whether the process can still touch the
    shared stream map, sidebar/session path, project state, and Hermes state.db
    without hitting the RST-before-write failure mode from #1458.

    `stream_check` is the result from a prior `_streams_lock_health()` call;
    if provided, it's reused so we don't acquire `STREAMS_LOCK` twice on the
    same /health?deep=1 request (per Opus advisor on stage-297).
    Nstreams_lockr  r  stream_runtimeFr  r   )r  r   rp  r1  r   )r  r   rp  )_migrateprojectsr  )r  rp  state_dbzPRAGMA schema_versionc              3   D   K   | ]}|                     d           dv V  dS )r  >   r  r  Nr   )r   checks     r   rx   z&_deep_health_checks.<locals>.<genexpr>  sH         			(00     r   )rw  r  r?   rK  r  ro   rM  r[   r  r  r  r  rz   r   sqlite3connectr   executefetchoneallr,  )	r  checksrt  r1  r  r  db_pathconnhealthys	            r   _deep_health_checksr    s    !F-9-E\\K_KaKaF>$ 
%
'
' F n!!(++t33u}	B
>>]]r)T1155
 
z
  
 
 
#YY'r)T1155
 
z
 
B
 %000]]r)T1155
 
z
  
 
 
#YY'r)T1155
 
z
 
B
'))~~ 	#TY[[2-5q99" "F:
 W6677 A4455>>@@@A A A A A A A A A A A A A A A TY[[2-5q99" "F:  
 
 
#YY'r)T1155
 
z
   ]]__    G 7?sr   $A	B. .
D8A C==DAE% %
F9/A F44F9A>J; (J6J; JJ; 	J
0J; ;
LA L

Lc           
         t          |j        pd                              ddg          d                                         dv }t	                      }t                      }|                    d          dk    rdndt          t                    t          |                    d          pd          t          |                    d	          pd          |                    d
g           |                    d          t          t          j
                    t          z
  d          t          |           d}d|v r|d         |d<   d|v r|d         |d<   |rc|                    d          dk    rd|i|d<   t          | |d          S t          |          \  }}||d<   |sd|d<   t          | |d          S |d         dk    rt          | |d          S t          | |          S )NrI   deepr   >   rJ   rM   rL   rK   r  r  degradedrq  r  r  r  r   )r  r1  rq  r  r  r  uptime_secondsaccept_loopr  r  r  r    r5  )r  )r   rN   r?   r   rw  r  ro   r  r  rM  rK  r  rl  r(  r  )r6  r7  r  r  	run_checkr   r  r  s           r   _handle_healthr    s   FL&B''++FRD99!<BBDDHbbD'))L%''I&**844<<$$*MMl../?@@EAFF9==77<1==fb)) ).D E E	.? ?CC*733	 	G  9,,,56N,O()$	111:;X1Y-. 3H%%--!/ >GHWgc2222-<HHH" 	3 *GHWgc2222xD  '#....Wgr   )pre_tool_callpost_tool_callpre_llm_callpost_llm_callc                  "    ddl m}   |             S )zDReturn Hermes Agent's plugin manager for read-only WebUI visibility.r   r  )r  r  r  s    r   "_get_plugin_manager_for_visibilityr    s#    555555r      r`  c                0   | dS t          |                               dd                                          }d                    |                                          }t          |          |k    r"|d|dz
                                           dz   }|S )zAReturn bounded display text without path/callback-like internals.NrI    r3  r      …)r   r%  r   r  r   ro   rc  r  s      r   _clean_plugin_visibility_textr    s    }ru::fb))//11D 88DJJLL!!D
4yy5KeaiK ''))E1Kr   c                    | pt                      } |                     d           g }t          | di           pi }t          |                                d           D ]\  }}t          |dd          }|t          t          |dd          p|pt          |d	d
          d          }t          t          |d	d
          p|d          }t          t          |dd
          d          }t          t          |dd
          d          }	t          t          |dd
          pdd          }
t          t          |dd                    }|
dk    rd}n|
dk    r|rd}n|rdnd}g }t          t          |dg           pg           t          t          |dg           pg           z   D ]G}t          |pd
          	                                }|t          v r||vr|                    |           H|                    t          j                   |                    ||p|||	||
||d           |t          |           t          t                    ddS )a  Build a sanitized plugin/hook visibility payload for Settings.

    The Hermes Agent manager stores manifests and callback objects internally.
    This endpoint intentionally exposes only safe, user-facing metadata and the
    four lifecycle hook names called out by the Settings visibility MVP. It
    never includes plugin source paths, callback names, callback reprs, or raw
    load errors because those can contain private filesystem details.

    Exclusive plugins (e.g. memory providers) are activated through their
    category's ``<category>.provider`` config, not through ``plugins.enabled``.
    Their ``loaded.enabled`` stays False by design and they register hooks
    outside the four visibility hooks below. The payload surfaces ``kind``
    and ``activation`` so the panel can render them distinctly instead of
    mislabeling them as "Disabled" with no hooks (issue #2659).
    Fforce_pluginsc                 ,    t          | d                   S r  r  r}  s    r   r  z,_plugin_visibility_payload.<locals>.<lambda>@  s    CQLL r   r  manifestNr8  r   rI   x   r  versionr.   r   i  kind
standalone(   r  	exclusivezmodel-providerr  r   provides_hookshooks_registered)r   r8  r  r   r  r  
activationhooksT)pluginsr  supported_hooksr  )r  discover_and_loadr@   r   r  r  r  ra  r   r   _PLUGIN_VISIBILITY_HOOK_SETr   r  _PLUGIN_VISIBILITY_HOOKSindex)managerr  raw_pluginsr8  loadedr  
plugin_keyr   r  r   r  enabled_flagr  
registeredhook	hook_names                   r   _plugin_visibility_payloadr  +  s     =;==GE***G':r228bKk//117P7PQQQ $ $V6:t442HeT**RcRWXvr5R5R
 
 

 -WXvr-J-J-Xj`cddd/)R0P0PXZ[[[3GHmUW4X4X`cddd,WXvr-J-J-ZlbdeeeGFIu==>>;$JJ%%%,%#JJ&2B
J
+;R@@FBGG$wW]_qsuOvOvO|z|J}J}} 	- 	-DDJB--//I777IZ<W<W!!),,,4:;;;%& $$
 
 	 	 	 	 ']]" 899	  r   c           
          	 t          | t                                S # t          $ rM}t                              d|           t          | g dt          t                    ddd          cY d }~S d }~ww xY w)Nz-Failed to build plugin visibility payload: %sT)r  r  r  r  unavailable)r(  r  r[   r   r~  ra  r  )r6  r7  r  s      r   _handle_pluginsr  n  s    
466777 
 
 
FLLL#'(@#A#A!# 	
 	
 		
 		
 		
 		
 		
 		

s    
A5AA0*A50A5u  <!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Hermes is restarting</title>
</head>
<body style="margin:0;padding:2rem;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#111827;color:#e5e7eb;">
  <main style="max-width:40rem;margin:10vh auto;line-height:1.5;">
    <h1 style="font-size:1.5rem;margin:0 0 0.75rem;">Hermes is restarting…</h1>
    <p style="margin:0;color:#cbd5e1;">The WebUI shell could not load cleanly. Refresh in a moment if this page does not update automatically.</p>
  </main>
</body>
</html>r  c                 l    t                               d|           t          | t          dd           dS )z?Return HTML for shell-route failures so `/` never renders JSON.z%Failed to serve WebUI shell route: %sr  text/html; charset=utf-8)r  content_typeT)r   r~  rT  _SHELL_ERROR_HTML)r6  r  s     r   _serve_shell_unavailabler    sA    
NN:C@@@/	    4r   c                     t          | ddi           ddlddl}fd} |j        |d                                           dS )z#Shut down the WebUI server process.r  shutting_downr   Nc                      dd l }  | j        d           t          j        t          j                    j                   d S )Nr   g333333?)rK  sleepr]   killgetpidSIGINT)rK  signals    r   _do_shutdownz&_handle_shutdown.<locals>._do_shutdown  s;    
3
	V]+++++r   Tr  daemon)r(  r  	threadingThreadr  )r6  r  r  r  s      @r   _handle_shutdownr    sq    g/*+++MMM, , , , ,
 IL666<<>>>4r   c                 ,   t          t                    j        j        dz  }|dz                                  }|                                r|                                }|                     d           |                     dd           |                     dd           |                     dt          t          |                               | 
                                 | j                            |           d	S t          | d
did          S )aC  Serve static/manifest.json with the correct PWA Content-Type.

    Shared by the root (/manifest.json, /manifest.webmanifest) and
    session-prefixed (/session/manifest.json, /session/manifest.webmanifest)
    routes so Firefox Android can fetch the manifest when installing from
    a /session/<id> page.  See #2226.
    staticzmanifest.jsonr   Content-Typez(application/manifest+json; charset=utf-8Cache-Controlno-storer  Tr   	not foundr4  r5  )r   __file__r   re   rz   r  r  r  r   ro   r  wfilewriter(  )r6  static_rootmanifest_pathdatas       r   _serve_manifestr    s     x..'.9K ?2;;==M ''))c"""N,VWWWOZ888,c#d))nn===D!!!tWw,S9999r   c                 lf   |j                             d          r@|                    |j         t          d          d                   }t	          | |          S |j         dv rt          |           S |j         dv s|j                             d          r(	 dd	lm} dd
lm	}  ||d          }ddl
m} d}	 ddlm}m}	m}
m}  |	            r% |
|           }|r ||          r ||          pd}n# t"          $ r d}Y nw xY wt%          j        d                              d|                              dt+          t,                                                  dt/          j        |                    }t3          |  ||          d          S # t"          $ r}t5          | |          cY d}~S d}~ww xY w|j         dk    r!t7                      }t9          j        |                    d          pd          }|                    dd          }t>          tA          |                   }dd	lm} dd
lm	}  ||d          }tB                              d|                              d|d         "                                                              d|                              dt9          j        |d                                                 d t9          j        |d!                                                 d"t9          j        |d#                                                 d$t9          j        |d%                                                 d&t9          j        |d'                                                 d(t9          j        |d)                                                 d*t9          j        |d+                             }t3          | |d          S |j         d,k    rdd-lm#}m$}m}	m}
m} dd.l%m&} d/} |	            }|r% |
|           }tO          |o
 ||                    } |            }|r
 |            ng } |            du}tQ          | |||tO          |          o| tO          |          t          |          |d0          S |j         d1v rt          |           S |j         d2k    rptS          tT                    j+        j+        d3z  }|d4z  ,                                }|-                                rdd	lm} dd
lm	}  ||d          }|                    d                              d|          }|.                    d          } | /                    d5           | 0                    d6d7           | 0                    d8d9           | 0                    d:d;           | 0                    d<t+          t          |                                | 1                                 | j2        3                    |            d=S tQ          | d>d?id@A          S |j         dBk    r?tS          tT                    j+        j+        d3z  }|dCz  ,                                }!|!-                                r|!4                                r|!5                                } | /                    d5           | 0                    d6dD           | 0                    d<t+          t          |                                | 0                    d8dE           | 1                                 | j2        3                    |            n)| /                    dF           | 1                                 d=S |j         dGk    rtm          | |          S |j                             dH          r)ddIl7m8}"  |"| |          }#|#d/u rts          | |dJ          S d=S |j         dKk    rtu          | |          S |j         dLk    rtw          | |          S |j         dMk    rty          | |          S |j         dNk    rtQ          | t{                                S |j         dOk    rtQ          | t}                                 d=S |j         dPk    rtQ          | t                                S |j         dQk    rt          | |          S |j         dRk    rddSlAmB}$ tQ          |  |$                      S |j         dTk    r*ddUlCmD}% tQ          | |%E                                           d=S |j         dVk    rbddUlCmD}% 	 tQ          | |%F                                           n6# t          $ r)}t          | t+          |          dWA           Y d}~nd}~ww xY wd=S |j         dXk    rtQ          | t                                S |j         dYk    rt          | |          S |j         dZk    rt          |jL                  }&|&                    d[dg          d         pd}'|&                    d\dg          d         pdM                                N                                d]v }(tQ          | t          |'|(^                    S |j         d_k    rt          |jL                  }&|&                    d[dg          d         pd}'|&                    d`dag          d         pdaM                                })	 t          dbt          t          |)          dc                    }*n# t          t          f$ r dd}*Y nw xY wtQ          | t          |'|*                    S |j         dek    rt7                      }+|+U                    dfd           tO          t          jW        dgd          M                                          |+dh<   	 ddilmX},m	} ||+dj<   |,|+dk<   n# t"          $ r Y nw xY wtQ          | |+          S |j         dlk    rt          |jL                  }&|&                    dmdg          d         pdM                                pd}-|&                    d[dg          d         pdM                                pd}'|&                    dndg          d         pdM                                pd}.tQ          | t          |-|'|.o                    S |j         dpk    rtQ          | t                                S |j                             dq          rddrl
m[}/  |/| |          S |j                             ds          rt	          | |          S |j         dtk    rt          |jL                  }&|&                    dudg          d         }0|0st          | dvdWA          S 	 t          |0d=w          }1n"# t          $ r t          | dxd@A          cY S w xY w	 ddyl^m_}2 tQ          | dz |2|1          i          S # t          $ r)}t          | t+          |          dWA          cY d}~S d}~wt"          $ rD}t          a                    d{|0           t          | t          |          d|A          cY d}~S d}~ww xY w|j         d}k    rAt          |jL                  }&t          | |&                    dudg          d                    d=S |j         d~k    	rddld}3|3e                                }4t          jf                            dd          }5t          |jL                  }&|&                    dudg          d         }0|0stQ          | d>dvidWA          S |&                    ddg          d         dk    }6|6rdnd}7|&                    d|7g          d         dk    }8|&                    ddg          d         }9	 |9rt          dbt          |9                    nd}:n# t          t          f$ r d}:Y nw xY w|&                    ddg          d         };	 |;rt          |;          nd}<n# t          t          f$ r d}<Y nw xY w	 |3e                                }=t          |0|6 w          }1t          |1dd          }>t          |1           t          |1          rt          |0          ni }?t          |1          pt          |?          }@g }Ag }Bd}Ct          |1dd          pd}D|@rt          |0          }An'|6rt          |0|D          }Bn|@st          |0|D          }C|3e                                }E|8rt          |1          nd}F|8rt          |1          nd}G|3e                                }H|6r<|@r|Art          |1|A          }Int          |1js        |Bt          |1dd                    }In\|@r&|Ar$t          |1dg           pg }Jt          |A|J          }In4|C t          t          |1dg           pg           }C|Cd         }K|Cd         }Lg }I|6sq|Ct          |I          }C|Cd         }K|Cd         }L|Kdk    rI	 t          |1dd          }M|Mt          dt          |M                    }Kn# t          t          f$ r Y n	w xY wnd}Kd}L|6rZt          |I|:|<          \  }N}O|<Bt          dt          t          |<          t          |I                              }P|Id|P         }Qng }Nd}O|6o'|:duo#|<dupt          |N          t          |I          k     }Rt          |1dd          pd}St          |1dd          pd}T|Sr|8rX|Fpt          |1dmd          pdM                                }Ut          |U|Gpt          |1dd          pd          }V|Vr|Sr|V|Sk    rd}T|V}S|6rt          |1dg           ng }W|6r|:t          |N          rg }Wn |Rrt          |W|Ot          |N                    }W|K|Knt          |I          }X|L|Lnd}Y|L6|Ir4	 t          d |ID                       }Yn# t          t          f$ r d}YY nw xY w|1y                                |N|X|Wt          |1dd          t          |1dd          |6rt          |1dg           ng t          |1dd          |S|Tt          |1dd          pdd
z  }Z|>rU	 t          |>          }[n# t"          $ r d}[Y nw xY w|[r0t          |[tO          t          |1dd                              |Zd<   |Yrjt          t          |Z                    d          pd          |Y          |Zd<   t          t          |Z                    d          pd          |Y          |Zd<   |?r$t          |?          rt          |Z|?          }Z|X|Zd<   |<|6o|:duot          |Q          |:k    }\n|6o|:duot          |I          |:k    }\|\|Zd<   |O|Zd<   |3e                                }]|Fr|F|Zdm<   |Gr|G|Zd<   t          |Z          }^|3e                                }_tQ          | d|^i          }`|3e                                }a|5rEt                              d|0|E|=z
  dz  |H|Ez
  dz  |]|Hz
  dz  |_|]z
  dz  |a|_z
  dz  |a|4z
  dz             |`S # t          $ r t          |0          }?t          |0          }b|bri du|0d!|?pi                     d!d          d|?pi                     dd          dm|?pi                     dmd          dt          |b          d|?pi                     dd          d|?pi                     dd          d|?pi                     d          p9|?pi                     dd          p!|br|bd         nddi                    dd          dd/dd/ddd|?pi                     d          dd=d|?pi                     d          d|?pi                     d          d|?pi                     d          d|?pi                     d          tO          |?pi                     d                    |bg d}ct          |c|?          }ctQ          | dt          |c          i          cY S t          | dxd@          cY S w xY w|j         dk    rt          |jL                                      dudg          d         }0|0st          | ddW          S t          t                      |0          }d|d                    d          st          | dxd@          S tQ          | |d          S |j         dk    r4ddlm}e tQ          |  |et          t                                          S |j         dk    rt          |jL                                      dudg          d         }0|0st          | d          S 	 ddlm}f t          t          |0d=w                     tQ          |  |f|0                    S # t          $ r t          | dxd@          cY S w xY w|j         dk    rat          |jL                                      dudg          d         }0|0st          | d          S tQ          | dt          |0          i          S |j         dk    rt          |jL                                      dudg          d         }0|0st          | d          S 	 ddlm}g tQ          |  |g|0                    S # t          $ r t          | dxd@          cY S w xY w|j         dk    rbt          |jL                                      dudg          d         }0|0st          | d          S ddlm}h tQ          | d |h|0          i          S |j         dk    rt          j        dJ|j         t          ¦          }i	 |i                    dæ           t          |iĦ          }j|i                    dŦ           t          |j          r&|i                    dƦ           t          |iĦ          }j|i                    dǦ           t7                      }+tO          |+                    dȦ                    }k|krT|i                    dɦ           t!                      }l|i                    dʦ           d˄ |lD             }m|jD ]}1|m                    |1                    du                    }n|ns-t          |n          rh|1                    t          |1|n                     |1                    du          |n                    du          k    r|n                    du          |1du<   dD ]7}o|1                    |o          s |n                    |o          r|n|o         |1|o<   8d̈́ |jD             }jd΄ |jD             ddlm fdЄ|lD             }pn#|i                    dѦ           d҄ |jD             }jg }p|i                    dӦ           |j|pz   }q|q                    dԄ d=զ           |i                    d֦           ddlm}r  |r            t/          |          }s|i                    dئ           |sr|q}td}un-fdل|qD             }tt          |q          t          |t          z
  }u|i                    dڦ           t1          |ttO          |+                    dۦ                    ܦ          }t|kr-|i                    dݦ           t3          |tt4          ަ          }t|i                    dߦ           g }v|tD ]i}1t7          |1          }wt9          |w                    d!          t*                    rt;          |wd!                   |wd!<   |v                    |w           j|i                    d           tQ          | |vt          |p          |s|ut          jd                    t          j        d          d          |i                                 S # |i                                 w xY w|j         dk    rtddlm}r  |r            tC                      }xt/          |          }s|sr|x}tnfd|xD             }ttQ          | |t|st          |x          t          |t          z
  d          S |j         dk    rtE          | |          S |j         dk    r-tQ          | tG                      tI                      d          S |j         dk    rRt          |jL                  }y|y                    ddg          d         }ztQ          | tK          |z          |zd          S |j         dk    rtM          | |          S |j         dk    rtO          | |          S |j         dk    rtQ          | |          S |j         dk    rtS          | |          S |j         dk    rtU          | |          S |j         dk    rddlAm}{  |{             ddlAm}|  ||            }}|}                    di           }~|~                    di           }g }t9          |t6                    r|                                D ]\  }}d}t9          |t6                    r|                    dd          }n8t9          |t*                    r"|dd         t          |          dk    rdndz   }|                    ||d           tQ          | d|i          S |j         dk    rt          |jL                  }y|y                    dudg          d         }0|0st          | d          S 	 t          |0          }1n!# t          $ r t          | dxd@          cY S w xY wddlm}m} 	  |tS          |1j                            }n## |$ r}te          | |          cY d}~S d}~ww xY w|                    d          pi }|                    d          sdn|                    d          |                    dd          |                    d d          pd|                    dd          pdz   |                    dd          |                    dd          |                    dd          d=d}tQ          | d|i          S |j         dk    r"ddlm} tQ          | d	 |            i          S |j         d
k    r"t7                      }+|+                    dd=          stQ          | dd=i          S tO          |+                    d                     }t          |jL                  }y|y                    ddg          d         dk    }|y                    ddg          d         dk    rK| j        d         dk    r9tQ          | ddddddddd|rdbnd| dddddddd          S ddlm} tQ          |  |||                     S |j         d!k    rt          |jL                                      d"dg          d         }|tn          v }||d/d#}	 |rt          |          nd}[n# t"          $ r d}[Y nw xY w|[rd=|d$<   t          |[|          |d%<   tQ          | |          S |j         d&k    rt          |jL                                      d"dg          d         }|st          | d'          S dd(lm}m}  |            r. |tv          )          }|                    |          j        }ntw          |          }tQ          | d=||d*          S |j         d+k    rt}          | |          S |j         d,k    rt          | |          S |j         d-k    rt          | |          S |j         d.k    rt          |           S |j         d/k    rt          | |          S |j         d0k    rt          | |          S |j         d1k    rt          | |          S |j         d2k    rt          | |          S |j         d3k    rt          | |          S |j         d4k    rt          | |          S |j         d5k    r7| j        d         dk    rtQ          | d>d?id@A          S t          | |          S |j         d6k    rt          | |          S |j         d7k    rt          | |          S |j         d8k    r7| j        d         dk    rtQ          | d>d?id@A          S t          | |          S |j         d9k    rt          |jL                  }y|y                    d:dg          d         }	 tQ          | t          |          d8d9i;          S # t          $ r'}t          | t+          |                    cY d}~S d}~wt          $ r(}t          | t+          |          d@          cY d}~S d}~ww xY w|j         d<k    r\dd=lm} dd>lm}  |            5  tQ          | d?t           |d=@                    i          cddd           S # 1 swxY w Y   |j         dAk    r:dd>lm}  |            5  t          | |          cddd           S # 1 swxY w Y   |j         dBk    r:dd>lm}  |            5  t          | |          cddd           S # 1 swxY w Y   |j         dCk    r:dd>lm}  |            5  t          | |          cddd           S # 1 swxY w Y   |j         dDk    r:dd>lm}  |            5  t          | |          cddd           S # 1 swxY w Y   |j         dEk    r:dd>lm}  |            5  t          | |          cddd           S # 1 swxY w Y   |j         dFk    r9dd>lm}  |            5  t          |           cddd           S # 1 swxY w Y   |j         dGk    rzt          |jL                  }y|y                    dHdg          d         }t          t                      |I          } tQ          | dJ|                     dJg           i          S |j         dKk    rt          |jL                  }y|y                    dLdg          d         }|stQ          | d>dMidWA          S |y                    dNdg          d         }|r1ddl} |j        dO|          rt          | dPdW          S t                      }t          |t          |                    \  }}|st          | dQd@          S ||z  ,                                }	 |                    |,                                           n"# t          $ r t          | dRdW          cY S w xY w|-                                r|4                                st          | dSd@          S tQ          | |                    d          |dT          S t          |          } t9          |                     dU          t6                    si | dU<   tQ          | |           S |j         dVk    rt          |           S |j         dWk    r-ddXlm}m}r tQ          |  |             |r            dY          S |j         dZk    r:dd[lm}rm} tQ          |  |r            t+           |                      d\          S |j         d]k    rddl}t                      }t                      }t{                      }|                    d^          }|d=u rd=}d=}n'|d/u rd/}d=}ntO          |          }tO          |          }t                      }|                                D ]V}n|n                    d          p|n                    d_          pd}Zt          |Z          }|r|                    |           Wd`dadbdcdddedft          fdg|D             dh i          }d}|rk|-                                rW	 |                                j        }|j                            |                                          }n# t"          $ r Y nw xY wtQ          | ||||t          |          dj          S |j         dkk    rt          |           S |j         dlk    rt          |           S |j         dmk    rt          |           S |j         dnk    rt          | |          S |j         dok    rt          | |          S |j         dpk    rt          |jL                  }y|y                    ddg          d         }|st          | dq          S 	 ddrlm} tQ          |  ||                    S # t          $ r'}t          | t+          |                    cY d}~S d}~wt"          $ rD}t          a                    ds           t          | t+          |          d|A          cY d}~S d}~ww xY w|j         dtk    rt          |jL                  }y|y                    ddg          d         }|y                    dudg          d         }|r|st          | dv          S 	 ddwlm} tQ          |  |||                    S # t          $ r'}t          | t+          |                    cY d}~S d}~wt"          $ rD}t          a                    dx           t          | t+          |          d|A          cY d}~S d}~ww xY wd/S (y  z>Handle all GET routes. Returns True if handled, False for 404.z/session/static/z/sessionNr  )z/session/manifest.jsonz/session/manifest.webmanifest)r   z/index.htmlz	/session/r   )quote)WEBUI_VERSIONrI   safe)inject_extension_tags)csrf_token_for_sessionr  r  verify_sessionr   r   __WEBUI_VERSION____MAX_UPLOAD_BYTES____CSRF_TOKEN_JSON__r  )r  z/loginbot_nameHermeslanguager}  z{{BOT_NAME}}z{{BOT_NAME_INITIAL}}z{{WEBUI_VERSION}}z{{LANG}}r  z{{LOGIN_TITLE}}r  z{{LOGIN_SUBTITLE}}r  z{{LOGIN_PLACEHOLDER}}r  z{{LOGIN_BTN}}r  z{{LOGIN_INVALID_PW}}r  z{{LOGIN_CONN_FAILED}}r  z/api/auth/status)_passkey_feature_flag_enabledget_password_hashr  r  r  registered_credentialsF)auth_enabled	logged_inpassword_auth_enabledpasswordless_enabledpasskeys_enabledpasskeys_countpasskey_feature_flag)z/manifest.jsonz/manifest.webmanifestz/sw.jsr  zsw.jsr   r  z%application/javascript; charset=utf-8r  r  zService-Worker-Allowedr   r  Tr   r  r4  r5  z/favicon.icozfavicon.icoimage/x-iconzpublic, max-age=86400r  z/api/insights/api/kanban/)handle_kanban_getGETz/api/wiki/statusz	/api/logsz/healthz/api/health/agentz/api/system/healthz/api/modelsz/api/models/livez/api/model/auxiliary)get_auxiliary_modelsz/api/dashboard/statusdashboard_probe/api/dashboard/configr  /api/providersz/api/pluginsz/api/provider/quotar  refresh>   rJ   rM   rL   rK   )r"  z/api/provider/cost-historyr  7r   r  r3  /api/settingspassword_hashHERMES_WEBUI_PASSWORDpassword_env_var)AGENT_VERSIONr  webui_versionagent_version/api/reasoningr  base_url)r4  r  r,  z/api/onboarding/statusz/extensions/)serve_extension_static/static/z/api/session/worktree/statusr5   session_id is requiredr   Session not found)worktree_status_for_sessionr  z-failed to read worktree status for session %sr  z/api/session/compress/statusz/api/sessionHERMES_DEBUG_SLOWr  rJ   r  resolve_modelr  r  r:  rk  r  r  )r  r  r  r  )r  r  r\  threshold_tokensr5  r  c              3      K   | ]?}t          |t                    t          |pi                     d           pd          V  @dS )r  r   N)r=   r>   r  r?   r   r  s     r   rx   zhandle_get.<locals>.<genexpr>  sc       2 2%a..2qwBmmK88=A>>2 2 2 2 2 2r   r=  r>  r?  last_prompt_tokens)
r  r  r  r:  r=  r>  r?  r\  r4  r7  rQ  runtime_journalr  _messages_truncated_messages_offsetrA   zx[SLOW] session_id=%s get_session=%.1fms model_resolve=%.1fms compact=%.1fms redact=%.1fms json_write=%.1fms total=%.1fmsr  CLI Session	workspacer  r  rY  r  pinnedarchived
project_idr  r~  r%  r  r  r  )r  r  r  z/api/session/lineage/reportsession_id requiredfoundz/api/session/recovery/audit)audit_session_recoverystate_db_pathz/api/session/statuszMissing session_id)session_status/api/session/yoloyolo_enabledz/api/session/usage)session_usagez/api/background/status)get_resultsresultsz/api/sessionsr   r  diagreconcile_stale_stream_state)all_sessions_after_stale_stream_reconciler  show_cli_sessionsrt  merge_cli_sessionsc                      i | ]}|d          |S r  r   r   s     r   
<dictcomp>zhandle_get.<locals>.<dictcomp>F  s    ===AQ|_a===r   )r~  r%  r  r  c                 0    g | ]}t          |          |S r   r
   r   s     r   r{   zhandle_get.<locals>.<listcomp>U  s'    !]!]!]?YZ[?\?\!]!!]!]!]r   c                     h | ]
}|d          S r  r   r   s     r   r   zhandle_get.<locals>.<setcomp>V  s    EEEQ|_EEEr   )_hide_from_default_sidebarc                 \    g | ](}|d          vt          |           |          &|)S r  rU  )r   r   
_cron_hide	webui_idss     r   r{   zhandle_get.<locals>.<listcomp>X  se      K  K  KQ<	1Q1QVpqrVsVs1Q  }G  }G  HI  }J  }J1Qq1Q1Q1Qr   filter_webui_sessionsc                 0    g | ]}t          |          |S r   )r  r   s     r   r{   zhandle_get.<locals>.<listcomp>[  s'    !c!c!cC_`aCbCb!c!!c!c!cr   sort_sessionsc                 \    |                      d          p|                      dd          pdS )Nr  r  r   r   r   s    r   r  zhandle_get.<locals>.<lambda>`  s,    aee$566U!%%a:P:PUTU r   r  active_profiler  profile_filterc                 Z    g | ]'}t          |                    d                     %|(S r  rE   r?   )r   r   r`  s     r   r{   zhandle_get.<locals>.<listcomp>z  sJ     P P P,QUU9-=-=~NNP! P P Pr   messaging_deduper  r  r  )r  redact_sessionsresponse_writez%z)r1  	cli_countrH   r`  other_profile_countserver_time	server_tzz/api/projectsc                 Z    g | ]'}t          |                    d                     %|(S r  rc  )r   rw   r`  s     r   r{   zhandle_get.<locals>.<listcomp>  sJ     L L LA(y)9)9>JJLa L L Lr   )r  rH   r`  rh  z/api/session/exportz/api/workspaces)
workspacesr^  z/api/workspaces/suggestr  )suggestionsr  z/api/sessions/searchz	/api/listz/api/git/statusz/api/git/branchesz/api/git/diffz/api/personalitiesr#  rZ  r  personalitiesr   r.   r   r   r   z/api/git-infoGitWorkspaceError
git_statustotalsis_gitbranchrh  stagedunstaged	untrackedaheadbehind)rv  dirtymodifiedry  rz  r{  ru  gitz/api/commands)list_commandscommandsz/api/updates/checkcheck_for_updatesr   ignore_agent_updatesr  simulatez	127.0.0.1webuirm   abc1234def5678masterz(https://github.com/nesquena/hermes-webuizBhttps://github.com/nesquena/hermes-webui/compare/abc1234...def5678)r   r{  current_sha
latest_sharv  repo_urlcompare_urlaaa0001bbb0002z,https://github.com/NousResearch/hermes-agentzFhttps://github.com/NousResearch/hermes-agent/compare/aaa0001...bbb0002)r   r{  ignoredr  r  rv  r  r  )r  r  
checked_at)r  )r  include_agentz/api/chat/stream/statusr6   )rR  r6   replay_availabler  journalz/api/chat/cancelzstream_id requiredLegacyJournalRuntimeAdapterruntime_adapter_enabled)cancel_delegate)r  	cancelledr6   z/api/chat/streamz/api/terminal/outputz/api/sessions/gateway/streamz/api/sessions/eventsz
/api/mediaz/api/file/rawz/api/folder/downloadz	/api/filez/api/approval/pendingz/api/approval/streamz/api/approval/inject_testz/api/clarify/pendingz/api/clarify/streamz/api/clarify/inject_testz/api/onboarding/oauth/pollflow_idextra_headersz
/api/crons	list_jobscron_profile_contextrq  include_disabledz/api/crons/outputz/api/crons/history/api/crons/runz/api/crons/recentz/api/crons/statusz/api/crons/delivery-optionsz/api/skillsr   r   rV   z/api/skills/contentr   name requiredr  z[*?\[\]]Invalid skill nameSkill not foundzInvalid file pathFile not found)r   r    r  z/api/memoryz/api/profiles)rt  r  )profilesrR  z/api/profile/active)r  rU   )r   r    z/api/gateway/statusaliver6  TelegramDiscordSlackEmailWebAPI)telegramdiscordslackemailwebr  c                 f    g | ]-}|                     ||                                          d .S ))r   label)r?   r  )r   rw   _PLATFORM_LABELSs     r   r{   zhandle_get.<locals>.<listcomp>$  s:    ]]]!a"2"6"6q!''))"D"DEE]]]r   c                     | d         S )Nr  r   )xs    r   r  zhandle_get.<locals>.<lambda>%  s
    !G* r   r  )runningr  	platformslast_activesession_countz/api/mcp/serversz/api/mcp/toolsz/api/notes/sourcesz/api/notes/searchz/api/notes/itemz/api/rollback/listz%workspace query parameter is required)list_checkpointszrollback/list failedz/api/rollback/diff
checkpointz6workspace and checkpoint query parameters are required)get_checkpoint_diffzrollback/diff failed)r    r   _replacero   _serve_staticr  urllib.parser  api.updatesr  api.extensionsr  r  r  r  r  r  r[   r
  r   r%  r   r  r  dumpsrT  r  r  _htmlescaper?   r  r  _LOGIN_PAGE_HTMLr  r  r  api.passkeysr  r  r(  r   r  r   re   rz   encoder  r  r  r  r  r   r  re  api.kanban_bridger  r8  r  r  r  r.  r0  r  _handle_live_modelsr`  r  r  r  get_dashboard_statusget_dashboard_configrh   r&  r2  r  r   rN   r   r   r3  r  r[  r  r  r4  rP  r]   r^   r(  r  r8  r-  r   r   api.worktreesr1  r   r  r+  _handle_session_compress_statusrK  r  r  r@   rP  r  ru  r  r  r  r  rT  rW  r  r  r  r  r  rl  r  r  r  r/  r[  r  r  r,  r~  r   r  api.session_recoveryrB  r  api.session_opsrE  rJ  rH  api.backgroundrI  r/  maybe_startstager  rj  rt  r	  rG  rW  r  rZ   r  rR   r  r  CLI_VISIBLE_SESSION_CAPr>   r=   r-  r   rK  finishr  _handle_session_exportr  r  r!  _handle_sessions_search_handle_list_dir_handle_git_status_handle_git_branches_handle_git_diffr#  r[  r  api.workspace_gitrr  rs  r<  _git_badapi.commandsr  r  r  r  api.runtime_adapterr  r  r.  
cancel_runaccepted_handle_sse_stream_handle_terminal_output_handle_gateway_sse_stream_handle_session_events_stream_handle_media_handle_file_raw_handle_folder_download_handle_file_read_handle_approval_pending_handle_approval_sse_stream_handle_approval_inject_handle_clarify_pending_handle_clarify_sse_stream_handle_clarify_injectr<  r  r  r  rr  _handle_cron_output_handle_cron_history_handle_cron_run_detail_handle_cron_recent_handle_cron_status_handle_cron_delivery_optionsr   ra   researchr   r   rf   r   _handle_memory_readrt  rU   r  rG  r3  r   r,  r&  r   r   r=  r?  r  r  _handle_mcp_servers_list_handle_mcp_tools_list_handle_notes_sources_list_handle_notes_search_handle_notes_itemapi.rollbackr  r  )r6  r7  r  r  r  version_tokenr  
csrf_tokenr  r  r  r  r  htmlr  	_settings_bn_lang_login_strings_pager  r  r  r  r  cvpasskey_flagpasskeysr  r  sw_pathr.  r  ico_pathr  r   r  r  rN   r  r"  days_rawr  settingsr(  r4  r,  r-  r   r   r1  rN  _t0_debug_slowload_messagesresolve_model_defaultr3  
_msg_limitr  _msg_beforer  _t1original_stream_idr  is_messaging_sessionr  state_db_messagesmetadata_summary_session_profile_t2rH  rN  _t3	_all_msgsr  _summary_message_count_summary_last_message_atmetadata_count_truncated_msgsr:  _before_idx_slice_windowed_messages_persisted_cl_threshold_tokens_model_for_lookup_fb_cl_session_tool_calls_merged_message_count_merged_last_message_atrQ   r  
_truncated_t4redact_t5resp_t6msgssessreportrB  rE  rH  rI  rM  webui_sessionsrP  r  	cli_by_idr  r8  deduped_clir  r  rH   scopedrh  safe_mergedr  all_projectsrP   r  _reload_cfgr  _cfg	agent_cfgraw_personalitiesro  r   r-  descrr  rs  r  r   rt  r  r  include_agent_updatesr  r  r6   rR  r   r  r  adapterr  r  r  r  r   	file_pathr  rp   r   	_skill_mdr  rt  rU   r  identity_mapsessions_pathhealthr  r  r  platforms_setnormr  r  r!   r<  r  r  r  r  rY  r`  rZ  s                                                                                                                                                                                    @@@@r   
handle_getrI    sa=    {011 0 ??C
OO4D4D(E?FFWh/// {QQQw'''{***fk.D.D[.Q.Q*	:******111111!E-b999M<<<<<<J jjjjjjjjjjjj"?$$ N!-g!6!6J! NnnZ&@&@ N%;%;J%G%G%M2
      


  !*G<<<,m<</5E1F1FGG.
:0F0FGG	  %%d++7   
  	: 	: 	:+GS99999999	: {h!OO	l9==44@AAj$//&%e,,
 	'&&&&&------m"555$$^S99W+SV\\^^<<W(-88WZnV.D!E!EFFW&^G5L(M(MNNW)5<z8R+S+STTW'n]6S)T)T  W_el>%3H&I&IJJW+U\.:V-W-WXXW'n]6S)T)T  	  %.HIIII{(((||||||||||||||777777	&(( 	8g&&BR6NN2$6$677I4466/;C))+++ 1 1 3 34 ?("%:$(NN$P;P7P $X!(mm$0
 
   	 {AAAw'''{h8nn+2X=(1133>> 	 +*****111111!E-b999M$$g$66>>#] D ;;w''D!!#&&&0WXXX<<< 8#>>> 0#c$ii..AAA!!!M%%%47K0===={n$$8nn+2X=-/88::?? 
	"!1!1!3!3 
	"&&((D!!#&&&??? 0#c$ii..AAA1HIII!!!M%%%%!!#&&&!!!t {o%%000{n-- 	777777
 #"7F33U??+GVUCCCt{(((&w777{k!!GV,,,{igv...{)))466777{***	'.00111t{m##.00111{((("7F333 {,,,333333..00111{---''''''	'?7799:::t{---''''''	/g;;==>>>> 	/ 	/ 	/S#.........	/t {&&&-//*** {n$$w///{+++&&yybT2215=99Y--a06B==??EEGGKee,['JJJKKK{222&&yybT2215=IIfse,,Q/63==??	q#c(mmS1122DDI& 	 	 	DDD	3KFFGGG{o%% ??_d+++
 (,I-r2288::(
 (
#$
	@@@@@@@@(5H_%(5H_%% 	 	 	D	(###{&&& &&IIgt,,Q/52<<>>F$yybT2215;BBDDLIIj2$//28b??AAIT !'!  
 
 	
 {.../11222{n-- 7999999%%gv666{j)) .Wf--- {444&&iird++A. 	Fw 8EEEE	ACt444AA 	A 	A 	Aw 3C@@@@@@	A	BAAAAAAWx)D)DQ)G)GHIII 	6 	6 	6wC555555555 	B 	B 	BLcRRRw 4 4SAAAAAAAAA	B {444&&'<"1N1Nq1QRRRt{n$$oojnn%8"==&&iird++A. 	OWw(@A#NNNN
 		*se44Q73>'4 =#		/4I3JKKANRUU
 YY{TF33A6
	3=GAs:///4III& 	 	 	III	
 iitf55a8	-8B[)))dJJI& 	 	 	JJJ	~	://##CCM0ACCCA!(,>!E!E%a(((<abc<d<dl3C888jlH#?#B#B#lFbckFlFl L "#&q)T::Bd# 
a7<< a$A#O_$`$`$`!!) a $B#O_#`#`#` //##C !<Q???  !EaHHH 
 //##C #' L  !EQ U UII B
)-4Q8NPT-U-U! ! !II ( #L #'.q*b'A'A'GR$ B<Qa b bII'/+;GAzSU<V<V<\Z\+]+](-=o-N*/?@Q/R, "I  0#+'7	'B'B$-=o-N*/?@Q/R,)Q..)04Mt)T)T)558C<O<O5P5P2%z2    / *.&+/( %4O')5 5 51!1
 )"%aS__c)nn)M)M"N"NK&||4F"$#$   VT)Vt+Ts?/C/Cc)nn/T " $A'7;;@qM '+=q A A FQ! +m +#Dwq'2'>'>D"%'' " C%&R'!5Et*L*LRPR   +$ .=)@)@ -.)$*MBO"W'!\2">">">UW)3ODD * ')### &D'$((' '#
 ?U>`$:$:fijsftft!BZBf&>&>lm#'/I/0.1 2 2!*2 2 2 / /++
 ":. 0 0 0./+++0))+++!61$+A/A4$H$H(/3I4(P(PP]'ewq2G'L'L'Lce&-a1Et&L&L"/$5&-a1Eq&I&I&NQ! ! C " 	#./ABBGG  # # #"GGG# -H#GA/A4$H$HII. . .C)* ' ),#''"3449::+* *%& %(#'',//4155+% %L!  =8BB =1#x@@ (=O$
 %*`y/D`VW`I`

*cy/DcYZcIc
)3C%&&6C"#//##C /.G! ;(:$%(--F//##CWy&122D//##C RWdNSWdNSWdNWdNSWdNSWdN   K 	: 	: 	:3C88H+C00D J #hn"11'=II  (.b!5!5k2!F!F hn"11'9EE	
 $SYY !8>r"6"6|Q"G"G !8>r"6"6|Q"G"G &B';';<M'N'N (T B++L!<<(T$(>R{A.>CCKQRSS e  !$ B33I>> %d  !8>r"6"6|"D"D!" !8>r"6"6|"D"D#$ %x~2&:&:;K&L&L%& #X^$8$8$H$H'( "&x~2&:&:;&G&G!H!H $"$-  0 34BB9.A$.G.G"HIIIIIw 3S99999?	:B {333v|$$((t<<Q? 	<w 5s;;;,-B-D-DcJJzz'"" 	:w 3S999&!!!{333??????00LaLcLcdddeee{+++v|$$((t<<Q? 	6w 4555	:666666%k#T&J&J&JKKKWnnS11222 	: 	: 	:w 3S99999	: {)))v|$$((t<<Q? 	6w 4555>+B3+G+GHIII{***v|$$((t<<Q? 	6w 4555	:555555WmmC00111 	: 	: 	:w 3S99999	: {...v|$$((t<<Q? 	6w 4555......9kk#&6&67888{o%%!-eV[PPPa	JJ~&&&)t444NJJ5666=nMM 9

FGGG!-4!8!8!8JJ'''$H $X\\2E%F%F G G  !

-...&((

/000=====	' 3 3A$==|)<)<==D ! 3D99 3!<Q!E!EFFF55..$((<2H2HHH.2hh|.D.DAlO#a 3 3C#$55:: 3$((3-- 3)-c#3
 "^!]^!]!]!]EEnEEE	OOOOOO K  K  K  K  K#  K  K  K

2333!c!c^!c!c!c JJ'''#k1FKKUU    $ JJ'(((<<<<<<4466N3F;;LJJ'((( @&'##P P P PV P P P&)&kkCKK&?#JJ)***>15LL!CDD2 2  F ! [

9%%%1&BYZZZJJ()))K ) )Awwdhhw//55 @$0g$?$?DM""4((((JJ'(((W' -- ,"0':#y{{!]400    KKMMMMDKKMMMM{o%% 	9888880022$/77 	L!FFL L L L L L LF(,#&|#4#4s6{{#B	
 
   	 {+++%gv666{'''O$5$5?Q?S?STT
 
 	
 {///fl##2$''*9&AA  
 
 	
 {,,,&w777{k!!000{'''!'6222{)))#GV444{o%%000{*** 	<;;;;;555555xzzHHWb))	%MM/2>>'.. 	J06688 J JeeT** K 99]B77DDs++ K ":#e**r//rJD$$d4%H%HIIII?M:;;;{o%%fl##ff\B4((+ 	7w 5666	:C  AA 	: 	: 	:w 3S99999	:CCCCCCCC	(ZQ[ 1 122FF  	( 	( 	(GQ''''''''	(H%%+!::h// 
ttjj**ZZ	1--Ha005A&**ZQR:S:S:XWXYK33ZZ++jj1--6
 6
 5$-((({o%%......:}}7888{*** ??||/66 	2Wz40111$(6L)M)M$N$N Nfl##w&&q)S0 FF:u%%a(C//&q)[88 !("#'0&/"*$N'k  !('<"C!!!'<#<'0&/"*$R'o	 	 #$)   2 	211111++%G\]]]^^^{///V\**..{RDAA!D	g%#)QVWW	5>H&y111DGG 	 	 	GGG	 	U*.G&'!<WV!T!T!TGI'"""{(((V\**..{RDAA!D	 	6w 4555\\\\\\\\""$$ 	111-PPPG**955>II%i00IIIVVWWW{(((!'6222{,,,&w777{444)'6:::{,,,,W555{l""Wf---{o%%000{,,,&w777{k!! &111{---'888{,,,*7F;;;{111!!$33Ww4SAAAA&w777{,,,&w777{+++)'6:::{000!!$33Ww4SAAAA%gv666{222fl##&&RD))!,		-*733.
;   
  	( 	( 	(wA'''''''' 	- 	- 	-wA,,,,,,,,	- {l""''''''555555!!## 	^ 	^Wv'9))UY:Z:Z:Z'['[\]]	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ 	^ {)))555555!!## 	8 	8&w77	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 {***555555!!## 	9 	9'88	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 {&&&555555!!## 	< 	<*7F;;	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< {)))555555!!## 	8 	8&w77	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 {)))555555!!## 	8 	8&w77	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 {333555555!!## 	: 	:099	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: {m##fl##66*tf--a0$%7%9%9HMMM8TXXh%;%;<==={+++fl##vvfrd##A& 	FWw8EEEEFF6B4((+	 	sz+t,, ?7$8#>>>+--J#6/
;;$ $ Iy  <7$5s;;;)+4466F>""9#4#4#6#67777 > > >7$7=====>==?? ;&..*:*: ;7$4c:::",,g,>>	RR   +400$((>22D99 	&#%D $ {m##"7+++ {o%%KKKKKKKK**,,8O8O8Q8QRR
 
 	

 {+++PPPPPPPP,,..<R<R<T<T8U8UVV
 
 	
 {+++9;;688" ,--

7##D==GJJe^^GJJ<((Gl++J"%%% '')) 	( 	(D((<((FDHHZ,@,@FBC.s33D (!!$'''" 
 
 ]]]]}]]]$$
 
 
	  	}++-- 	%**,,5&/==eDDNNPP   $"& ..
 
   	 {((('000 {&&&%g...{***)'222{)))#GV444{'''!'6222 {***fl##FF;--a0	 	Iw GHHH	4555555W..y99::: 	( 	( 	(wA'''''''' 	4 	4 	43444wAs333333333	4 {***fl##FF;--a0	VVL2$//2
 	Z
 	Zw XYYY	4888888W11)ZHHIII 	( 	( 	(wA'''''''' 	4 	4 	43444wAs333333333	4 5s  !F >;C: 9F :D	F D		BF 
G &F;5G ;G 8"e 
f%f		f'+l l)(l)1o 
oov v<;v<  w! !
y +x	y y 9yy y  ! 9A@ @A@#@"A@#@'G'AY H0AI  H?AY I AIIAY IAIIE<AY OAO+ O*AY O+APO>AY P APPA8AY Q:AR
 R	AY R
ARRAY RARRF9AY YG+Aaa AaaAaf<Ag gAggAgjAj: j:AkkAkm7P5A ALBL LBL1L0BL1L=BM MBM;M BM6M0BM;M6BM;XBX  X BX/X.BX/d4"Be e
Bf8e!Bfe=Bf8fBf8fBf3f-Bf8f3Bf8g,BhhBhhBhi BiiBi"i%Bi"jBj$j$Bj(j+Bj(kBk*k*Bk.k1Bk.lBl0l0Bl4l7Bl4mBm6m6Bm:m=Bm:nBn;n;Bn?oBn?u'Bu0 u0BvvBv@(ACA. A.
CA;A:CA;FCF! F!
CHF+CGGCHGCHG9CHHCHHCHJ CJ4 J4
CL1J>CK KCL1K CL1K-9CL,L&CL1L,CL1c                    t          j        d|j        t                    }|j        dk    rZ|r|                    d           	 t          |           |r|                                 S S # |r|                                 w w xY w|r|                    d           t          |j                  sdt          |           sU	 t          | dt          |           id          |r|                                 S S # |r|                                 w w xY w|j        d	k    rt          |           S |j        d
k    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    r4|r|                    d           t          | t!          |                     S |r|                    d           	 t#          |           n%# t$          $ r |r|                                  w xY w|j        dk    rMddlm}  |t*          t-                                }t          | ||                    d          rdnd          S |j                            d          r*ddlm}  || |          }|du rt7          | |d          S dS |j        dk    rddlm} 	 t          | |                                         n# t>          $ r)}tA          | tC          |          d           Y d}~nSd}~wt$          $ rC}t          "                    d           tA          | tC          |          d            Y d}~nd}~ww xY wdS |j        d!k    r	                     d"          r/tC          tG                              d"                              nd}n;# tH          t>          f$ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wd}
                    d#          du pGtC                              d#                    %                                &                                d$v }|r	 dd%l'm(} |}|s(tC          tG          tS                                          } ||          }
|
d&         }n~# tH          t>          f$ r)}	tA          | tC          |	          d          cY d}	~	S d}	~	wt$          $ r9}	t          "                    d'           tA          | d(|	 d           cY d}	~	S d}	~	ww xY wtU                              d)                              d*                    \  }}                    d+          }|r	 dd,l+m,} dd-l-m.}m/} d}|5  |                    |          }|r|d         }ddd           n# 1 swxY w Y    |||.           n-# t$          $ r  t          0                    d/|d0           Y nw xY wtc          |||                    d1          pd                    d2          pd|
3          }|
rte          d4           t          | d5|3                                d6|j4        iz  i          S |j        d7k    r	                     d8          }|stA          | d9          S tk          j6        |          }|stA          | d:d;          S tk          di d8to          j8                    j9        dd<         d=|j:        pd>d?z   d"|j;        d)|j<        d*|j=        d6t}          j?        |j4                  d@t}          j?        |j@                  dAddBdd2|jA        d1|jB        dC|jC        dD|jD        dE|jE        dF|jF        dGt          |dGd          dHt          |dHd          dIt          |dId          dJt          jH                    dKt          jH                    }t          5  |t          |jK        <   t          jL        |jK                   t          t                    t          k    r2t          jO        dL           t          t                    t          k    2ddd           n# 1 swxY w Y   |P                                 te          dM           t          | d5|3                                d6|j4        iz  i          S # t$          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w|j        dNk    r	 t          | t                              d)                              S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d           cY d}	~	S d}	~	ww xY w|j        dOk    rtC                              dP          pdQ          %                                }tC                              dR          pdQ          %                                }tC                              dS          pdT          %                                }tC                              d)          pdQ          %                                }|dUk    rXddVl-mS} 	 t          |  ||||                    S # t$          $ r)}tA          | tC          |          d          cY d}~S d}~ww xY w|dWk    rT	 t          | t          |                    S # t>          $ r)}tA          | tC          |          d          cY d}~S d}~ww xY wtA          | dX| d          S |j        dYk    r                    dS          pdQ%                                &                                }                    dZ          }|stA          | d[          S |#tC          |          %                                pd}t          ||          }|                    d\          s$tA          | |                    dd]                    S t          | |          S |j        d^k    r                    dS          pdQ%                                &                                }|stA          | d[          S t          |          }|                    d\          s$tA          | |                    dd]                    S t          | |          S |j        d_k    rI	                     d`          }                     da          }!| tC          |           %                                &                                }"|"dbv rt          | t          d                    S |"dcv rt          | t          d                    S tA          | dd|  de          S |!t          | t          |!                    S tA          | df          S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d           cY d}	~	S d}	~	ww xY w|j        dgk    r\ddlX}#ddhlmY}$ |#Z                    |$           ddl[m\}% |$j]        |%_]        |$j5        |%_5        |$j3        |%_3        t          | d\didj          S |j        dkk    rt          | dl          S |j        dmk    rt          | dl          S |j        dnk    r?	 t          d8d=           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 t          d8                   }t          d8         |          }n!# t          $ r tA          | d:d;          cY S w xY wt          d8                   5  tC          d=                   %                                ddo         pd>|_:        |P                                 ddd           n# 1 swxY w Y   te          dp           t          | d5|3                                i          S |j        dqk    r{	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wdrvrtA          | ds          S d8         }dr         %                                }&	 t          |          }t          ||          }n!# t          $ r tA          | d:d;          cY S w xY wdQ}'|&rYddtl-mc}(  |(             ddul-md})  |)            }*|*                    dvi           }+|+                    dwi           },t          |,t                    r|&|,vrtA          | dx|& dyd;          S |,|&         }-t          |-t                    r|-                    dzdQ          p|-                    d{dQ          g}.|-                    d|          r|.g                    d}|-d|                     |-                    d~          r|.g                    d|-d~                     dh                    d |.D                       }'ntC          |-          }'t          |          5  |&r|&nd|_F        |P                                 ddd           n# 1 swxY w Y   t          | d|jF        |'d          S |j        dk    rB	 	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wd8         }                    d          }/|/Pt          |/t                    r|/stA          | d          S t          d |/D                       stA          | d          S 	 t          |          }n!# t          $ r tA          | d:d;          cY S w xY wt          |          5  |/|_k        |P                                 ddd           n# 1 swxY w Y   t          | d|jk        d          S |j        dk    rq| jl        dk    rt          |jn                  }0|jn        r|0                    d8dQg          d         ndQ}|stA          | d9d          S 	 t          |          }n!# t          $ r tA          | d:d;          cY S w xY wt          |di           pi }1t          | d|1i          S 	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wd8         }                    d          }2                    d          }3d}4d}5|2t          |2tB                    sdQ}2t          |2tB                    rt          |2          |4k    r
|2d|4         }2|3t          |3t                    sg }3t          |3t                    rt          |3          |5k    r
|3d|5         }3	 t          |          }n!# t          $ r tA          | d:d;          cY S w xY wt          |          5  t          |di           pi }1|2|2|1d<   |3|3|1d<   |1|_o        |P                    dd           ddd           n# 1 swxY w Y   t          | d|jo        d          S |j        dk    r4	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 t          d8                   }n!# t          $ r tA          | d:d;          cY S w xY wt          |d"dQ          }6t          |d)d          }7t          |d*d          }8	 tC          tG                              d"|j;                                      }9n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wt          d8                   5  |9|_;        d)v sd*v r#tU                              d)|j<                  d*v r                    d*          ndt          |d*d                    \  }}|||_<        ||_=        tC          |7pdQ          tC          t          |d)dQ          pdQ          k    s3tC          |8pdQ          tC          t          |d*dQ          pdQ          k    rXt          t          |d)d          t          |d*d                    |_q        d|_r        d|_s        ddl-mt}:  |:d8                    |P                                 ddd           n# 1 swxY w Y   tC          |6pdQ          tC          |9pdQ          k    rC	 ddlumv};  |;d8                    n*# t$          $ r t          0                    d           Y nw xY wt          |9           t          | d5|3                                d6|j4        iz  i          S |j        dk    r                    d8dQ          }|r)t          |tB                    r|%                                stA          | dd          S |%                                }t          d |D                       stA          | dd          S 	 t          |d          }n"# t          $ r tA          | d:d;          cY S w xY wt                              dd                    }<	 ddl'my}=  |=||<          }t          | |          S # t>          $ r)}tA          | tC          |          d          cY d}~S d}~wt$          $ rD}t          "                    d|           tA          | t          |          d           cY d}~S d}~ww xY w|j        dk    r'                    d8dQ          }|stA          | d9          S t          d |D                       stA          | dd          S t          |          }>|>                    d          rtA          | dd          S t          |          }?t          |          }@t          5  t          j~        |d           ddd           n# 1 swxY w Y   ddl-mt}:  |:|           	 t*          | dz                                  }A|A                    t+          j                               n!# t$          $ r tA          | dd          cY S w xY w	 |A                    d           |A                    d                              d           n+# t$          $ r t          0                    d|A           Y nw xY w	 t          |           n-# t$          $ r  t          0                    d|d0           Y nw xY w	 ddlm}B t          j         |B|          d           n+# t$          $ r t          0                    d|           Y nw xY wt          5  t          j~        |d           ddd           n# 1 swxY w Y   	 ddlumv};  |;|           n+# t$          $ r t          0                    d|           Y nw xY w|?s>	 ddlm}C  |C|           n+# t$          $ r t          0                    d|           Y nw xY wte          d           t          | d\di|@          S |j        dk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 t          d8                   }n!# t          $ r tA          | d:d;          cY S w xY wd8         }t          |          5  g |_4        g |_@        d>|_:        |P                                 ddd           n# 1 swxY w Y   ddl-mt}:  |:|           t          | d|3                                d          S |j        dk    rq	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w                    d          tA          | d          S 	 t          d8                   }n!# t          $ r tA          | d:d;          cY S w xY wt          d                   }Dt          d8                   5  |j4        d|D         |_4        	 ddlm}E  |E|j4                  |_        n# t$          $ r
 d|_        Y nw xY w|P                                 ddd           n# 1 swxY w Y   t          | d|3                                d6|j4        iz  d          S |j        dk    r=	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wt          d8         tB                    stA          | d          S 	 t          d8                   }Fn!# t          $ r tA          | d:d;          cY S w xY w                    d          }G|GO	 t          |G          }Gn'# t>          tH          f$ r tA          | d          cY S w xY w|Gdk     rtA          | d          S                     d=          }H|Hr+tC          |H          %                                ddo         pd}H	 |FP                                 n# t$          $ r Y nw xY wt!          |F          rt          |FjK                  ni }It#          |F          pt#          |I          }?|?rt%          |FjK                  ng }J|?r|Jrt'          |F|J          nt          |Fj4        pg           }K|G|Kd|G         }Lnt          |K          }L|Hr|H}Mn|Fj:        pd>}N|N d}Mtk          |Fj;        |Fj<        t          |Fd1d          |M|L|FjK        d          }Ot          5  |Ot          |OjK        <   t          jL        |OjK                   t          t                    t          k    r2t          jO        dL           t          t                    t          k    2ddd           n# 1 swxY w Y   |Lr#|OP                                 te          d           t          | |OjK        |M|FjK        d          S |j        dk    rt)          |           S |j        dk    rt+          |           S |j        dk    rt-          |           S |j        dk    rt/          |           S |j        dk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 ddlm}P  |Pd8                   }t          | d\di|          S # t          $ r tA          | d:d;          cY S t>          $ r)}	t          | dtC          |	          i          cY d}	~	S d}	~	ww xY w|j        dk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 ddlm}Q  |Qd8                   }t          | d\di|          S # t          $ r tA          | d:d;          cY S t>          $ r)}	t          | dtC          |	          i          cY d}	~	S d}	~	ww xY w|j        dk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wd8         }t                              dd                    }R|Rrnt5          |           	 ddlm}Sm}T |T5  |S~                    |d           ddd           n# 1 swxY w Y   n# t$          $ r Y nw xY wt=          |dd̦           nt?          |           t          | d|Rd͜          S |j        dk    rtA          |           S |j        dk    rtC          |           S |j        dk    rtE          |           S |j        dk    rtG          | |Ҧ          S |j        dk    rtI          |           S |j        dk    rddlm}U  |U|           S |j        dk    rtO          |           S |j        dk    rtQ          |           S |j        dk    rtS          |           S |j        dk    rtU          |           S |j        dk    r9ddlm}V  |V            5  t[          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}V  |V            5  t]          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}V  |V            5  t_          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}V  |V            5  ta          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}V  |V            5  tc          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}V  |V            5  te          |           cddd           S # 1 swxY w Y   |j        dk    rtg          |           S |j        dk    rti          |           S |j        dk    rtk          |           S |j        dk    rtm          |           S |j        dk    rto          |           S |j        dk    rtq          |           S |j        dk    rts          |           S |j        dk    rtu          | d          S |j        dk    rtu          | d          S |j        dk    rtu          | d          S |j        dk    rtw          |           S |j        dk    rty          |           S |j        dk    rt{          |           S |j        dk    rt}          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rddlm}W tC                              d dQ          pdQ          %                                }X|XstA          | d          S 	 t          | d |W|X          i          S # t>          $ r(}	tA          | tC          |	          d          cY d}	~	S d}	~	wt          $ r tA          | dd;          cY S t          $ r(}	tA          | t          |	          d           cY d}	~	S d}	~	ww xY w|j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    r	                    drdQ          %                                }&|&stA          | d	          S 	 dd
lm}Ym}Z ddlm}[ |&dk    r |Z|&            |Y|&d          }ddl-m}\  |\             t          | |d |[|&          i          S # t>          t          f$ r(}	tA          | t          |	          d;          cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rz                    drdQ          %                                }&|&stA          | d	          S ddl}] |]j        d|&          stA          | d          S                     d          }^|^DtC          |^          %                                }^ |]j        d|^          stA          | d          S                     d          r)                    ddQ          %                                nd}_                    dZ          r(                    dZdQ          %                                nd}                    d          r)                    ddQ          %                                nd}`                    d*          r(                    d*dQ          %                                nd}|_r'|_                    d          stA          | d          S 	 ddlm}a  |a|&|^t                              dd                    |_||`|          }t          | d|d          S # t>          t          t          f$ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w|j        dk    r׉                    drdQ          %                                }&|&stA          | d	          S 	 ddlm}bm}Z  |Z|&            |b|&          }t          | |          S # t>          t          f$ r'}	tA          | t          |	                    cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d          cY d}	~	S d}	~	ww xY w|j        d k    r,dd!lm}cm}dm}em}fm}g d"v r1tC          d"                   pdQ%                                pd#d"<    |d            }h |e|           }it          |io
 |g|i                    }jt          t                              d$          tB                    o(                    d$dQ          %                                          }kt          ~                    d%d                    }lt                              d&          p|l          }m|lrdd&<   |ks|mr;t          j        d'dQ          %                                rtA          | d(d          S |lrGdd)lm}n dd*lm}o  |n            stA          | d+d          S  |o            stA          | d,d          S n|mrdd-lm}p  |p             t                    }q|q~                    d.d            |d            }rt          |ko|ro|h           }s|j}td}u|sr|js |c            }ud}t|r|qd/<   |t|qd0<   |s|qd1<   |ust          | |q          S t          j        |qdd23                              d4          }v|                     d           |                     d5d6           |                     d7tC          t          |v                               |                     d8d9            |f| |u           t          |            |                                  | j                            |v           dS |j        d:k    rdd;lm}d ddl}w |d            s|w                    d<          sddl}x	 | j                            d=dQ                              d>          d         %                                }y| j                            d?dQ          %                                }z| j        d         }{|x                    |yp|zp|{          }|||j        p||j        }}n# t>          $ r d}}Y nw xY w|}stA          | d@d          S 	 t          | t                    d8d9i          S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d           cY d}	~	S d}	~	ww xY w|j        dAk    rZ	 t          | t                    d8d9i          S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w|j        dBk    rdd;lm}d ddl}w |d            s|w                    d<          sddl}x	 | j                            d=dQ                              d>          d         %                                }y| j                            d?dQ          %                                }z| j        d         }{|yp|zp|{}~|x                    |~          }|||j        p||j        }}n# t>          $ r d}}Y nw xY w|}stA          | dCd          S 	 t          | t                              S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	wt          $ r(}	tA          | tC          |	          d           cY d}	~	S d}	~	ww xY w|j        dDk    rt          | t                                S |j        dEk    rdd;lm}d ddl}w |d            s|w                    d<          sddl}x	 | j                            d=dQ                              d>          d         %                                }y| j                            d?dQ          %                                }z| j        d         }{|yp|zp|{}~|x                    |~          }|||j        p||j        }}n# t>          $ r d}}Y nw xY w|}stA          | dFd          S tC          pi                     dS          pdQ          %                                &                                }tC          pi                     d          pdQ          }_tC          pi                     dZ          pdQ          %                                pd}	 t          | t          ||_|                    S # t$          $ r}	tA          | dG|	 d           cY d}	~	S d}	~	ww xY w|j        dHk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 t          d8                   }t          d8         |          }n!# t          $ r tA          | d:d;          cY S w xY wt                              dAd                    }|r`t          |dAd          sNdI t                      D             }t          5  t          |          }|                     dJ t          j                    D                        |                    d8                    t          t                                          dKdL          pdL          }t          |          |k    r#tA          | dM| dNd          cddd           S d|_        ddd           n# 1 swxY w Y   t          d8                   5  |P                                 ddd           n# 1 swxY w Y   nIt          d8                   5  ||_        |P                                 ddd           n# 1 swxY w Y   te          dO           t          | d|3                                d          S |j        dPk    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wd8         }	 t          |          }t          |dQd          rNtk          j6        |          }|t          |          t          5  |t          |<   ddd           n# 1 swxY w Y   n7# t          $ r) t          |          }I|IstA          | d:d;          cY S |I                    d          rtA          | dRd          cY S t#          |I          rtk          ||I                    d=          pt          t%          |          dS          tS                      g |I                    d)          pdT|I                    dJ          |I                    dK          U          }d|_        |I                    dV          |_        |I                    dW          p|I                    dV          |_        |I                    dX          |_	        |I                    dY          |_
        |I                    dZ          |_        |I                    d[          |_        |I                    d\          |_        |I                    d]          |_        |I                    d^          |_        |I                    d_          |_        |P                    d`           nt%          |          }|stA          | d:d;          cY S t#          ||I                    d=          pt          |dS          ||I                    d)          pdT|I                    d1          |I                    dJ          |I                    dK          a          }d|_        |I                    dV          |_        |I                    dW          p|I                    dV          |_        |I                    dX          |_	        |I                    dY          |_
        |I                    dZ          |_        |I                    d[          |_        |I                    d\          |_        |I                    d]          |_        |I                    d^          |_        |I                    d_          |_        Y nw xY wt          |          5  t                              dBd                    |_        |P                    d`           ddd           n# 1 swxY w Y   te          db           t          | d|3                                dt'          |                    S |j        dck    r	 t          d8           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY w	 t          d8                   }n!# t          $ r tA          | d:d;          cY S w xY w                    d2          pdrdddlm}  |            }t+          fdet-                      D             d          }|stA          | dfd;          S t/          |                    d1          |          stA          | dfd;          S t          d8                   5  |_A        |P                                 ddd           n# 1 swxY w Y   te          dg           t          | d|3                                d          S |j        dhk    rN	 t          dr           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wddl}]dddlm} dr         %                                ddi         }&|&stA          | dj          S                     dk          }|r# |]j        dl|          stA          | dm          S t-                      }to          j8                    j9        dd<         |&| |            pdt          jH                    dn}|g                    |           t1          |           t          | d|do          S |j        dpk    rW	 t          d2dr           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wddl}]dddlm} t-                      }t+          fdq|D             d          }|stA          | dfd;          S  |            }t/          |                    d1          |          stA          | dfd;          S dr         %                                ddi         |dr<   dkv r4dk         }|r# |]j        dl|          stA          | dm          S ||dk<   t1          |           t          | d|do          S |j        drk    r	 t          d2           n4# t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	ww xY wdddlm} t-                      }t+          fds|D             d          }|stA          | dfd;          S  |            }t/          |                    d1          |          stA          | dfd;          S fdt|D             }t1          |           t3          j                    r	 t          j        t3          j        d4u                    }|D ]}|                    d2          d2         k    rq	 t          |d8                   }d|_A        |P                                 S# t$          $ r2 t          0                    dv|                    d8                     Y w xY wn+# t$          $ r t          0                    dw           Y nw xY wt          | d\di          S |j        dxk    rt;          |           S |j        dyk    rO                    dzdQ          }|d{vrtA          | d|          S dd}lm} t          |  ||                    S |j        d~k    rO                    dzdQ          }|d{vrtA          | d|          S ddlm } t          |  ||                    S |j        dk    rddlm!} t          t                    r                    d          ni }t          t                    r                    dz          nd}dztB          dtB          dtB          fd}t          |  ||||                    S |j        dk    rtE          |           S |j        dk    rddlܐm#}m}cm}fm}d ddlܐm$}m%}  |d            st          | ddd          S | j        d         } ||          st          | ddid          S                     ddQ          } ||          s ||           tA          | dd          S  |c            }t          j        d\di                                          |                     d           |                     d5d           |                     d7tC          t                                         |                     d8d9           t          |             |f| |           |                                  | j                                       dS |j        dk    rddlm}nm}d ddlm&}m'}  |n            st          | ddid;          S  |d            st          | ddid          S 	 t          | d ||           d          S # |$ r)}	tA          | tC          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rddlm}nm}cm}dm}f ddlܐm$}m%} ddlm&}m(}  |n            st          | ddid;          S  |d            st          | ddid          S | j        d         } ||          st          | ddid          S 	  ||            n=# |$ r5}	 ||           tA          | tC          |	          d          cY d}	~	S d}	~	ww xY w |c            }|                     d           |                     d5d           |                     d8d9           t          |             |f| |           |                                  | j                            t          j        d\di                                                     dS |j        dk    rKdd)lm}n ddlm)}  |n            st          | ddid;          S t          | d ||           d          S |j        dk    rdd)lm}n ddlm&}m*}m}o  |n            st          | ddid;          S 	  ||           } |o            |d<   t          | |          S # |$ r)}	tA          | tC          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rddlm}nm+} ddlm&}m,}m}o  |n            st          | ddid;          S 	 tC                              d          pdQ           |o            } |            Ct          |          dk    r/t[          fd|D                       rtA          | dd          S t          |  |                    S # |$ r)}	tA          | tC          |	          d;          cY d}	~	S d}	~	ww xY w|j        dk    rGdd)lm}n dd*lm}o  |n            st          | g dd          S t          | d |o            i          S |j        dk    rddlܐm.}m/}m}e  |e|           }|r ||           t          j        d\di                                          |                     d           |                     d5d           |                     d7tC          t                                         |                     d8d9           t          |             ||            |                                  | j                                       dS |j        dk    rstA          | d          S                     d"dQ          }                    ddQ          }|r|stA          | d          S 	 ddl0m1} t          |  |||                    S # t>          $ r'}	tA          | tC          |	                    cY d}	~	S d}	~	wt$          $ rD}	t          "                    d           tA          | tC          |	          d           cY d}	~	S d}	~	ww xY wdS (  z?Handle all POST routes. Returns True if handled, False for 404.POSTrK  r  r&   csrfr     r5  z/api/shutdownz/api/uploadz/api/upload/extractz/api/transcribez/api/client-events/logread_client_event_bodyr)  z!/api/session/recovery/repair-safer   )repair_safe_session_recoveryrC  cleanr     r  )handle_kanban_postFTr   r  r  Nzdashboard config save failedr  z/api/session/newr<  worktree>   rJ   rM   rL   rK   )create_worktree_for_workspacer    z(failed to create worktree-backed sessionzFailed to create worktree: r  r5  prev_session_id)commit_session_memory)SESSION_AGENT_CACHESESSION_AGENT_CACHE_LOCK)r  z+Lifecycle commit for prev_session %s failedr   rk  r?  )r<  r  r5  rk  r?  worktree_infosession_newrA   r  z/api/session/duplicater5   r/  r0  r4     r  r  z (copy)r  r=  r>  r  r  r  personalityenabled_toolsetsr\  r4  r  r  r]  session_duplicatez/api/default-modelz/api/model/setscoperI   taskr  auto	auxiliary)set_auxiliary_modelmainzunknown scope: r!  api_keyzprovider is requiredr  zUnknown errorz/api/providers/deleter+  displayeffort)showrM   rK   rJ   )hider  r  r  z'display must be show|hide|on|off (got 'z')z,reasoning: must supply 'display' or 'effort'z/api/admin/reload)r2  z
api.models)r  reloadedz/api/sessions/cleanup)	zero_onlyz"/api/sessions/cleanup_zero_messagez/api/session/renamer.   session_renamez/api/personality/setr   zMissing required field: namern  rZ  r  ro  zPersonality "z" not found in config.yamlsystem_promptprompttonezTone: stylezStyle: r   c              3      K   | ]}||V  	d S r;   r   rv   s     r   rx   zhandle_post.<locals>.<genexpr>  s'      "9"9q"91"9"9"9"9"9"9r   )r  r\  rn  z/api/session/toolsetstoolsetsz)toolsets must be a non-empty list or nullc              3   D   K   | ]}t          |t                    o|V  d S r;   )r=   r   r   rT  s     r   rx   zhandle_post.<locals>.<genexpr>  s1      BBAz!S))/aBBBBBBr   z'each toolset must be a non-empty string)r  r]  z/api/session/draftr  composer_draftdraftr.  filesP  2   )rE  
skip_index)r  rv  z/api/session/update)_evict_session_agentclose_terminalz9Failed to close workspace terminal after workspace updatez/api/session/worktree/removez%session_id must be a non-empty stringc              3      K   | ]}|d v V  	dS %0123456789abcdefghijklmnopqrstuvwxyz_Nr   r   cs     r   rx   zhandle_post.<locals>.<genexpr>M  (      MMA1??MMMMMMr   zInvalid session_idr   r  )remove_worktree_for_sessionr  z(failed to remove worktree for session %sz/api/session/deletec              3      K   | ]}|d v V  	dS r  r   r  s     r   rx   zhandle_post.<locals>.<genexpr>c  r  r   r  z8Read-only imported sessions cannot be deleted from WebUIrC  
missing_okz	.json.bakz Failed to unlink session file %sz.Failed to prune deleted session from index: %s_session_attachment_dir)ignore_errorsz5Failed to clean attachment dir for deleted session %sz9Failed to close workspace terminal for deleted session %s)delete_cli_sessionzFailed to delete CLI session %ssession_deletez/api/session/clearr  rA   z/api/session/truncate
keep_countz%Missing required field(s): keep_count)_truncation_watermark_forrS  z/api/session/branchzsession_id must be a stringzkeep_count must be an integerzkeep_count must be non-negativez (fork)fork)r<  r  rk  r  r  r  r  session_branch)r5   r  r  z/api/session/compress/startz/api/session/compressz /api/session/conversation-roundsz/api/session/handoff-summaryz/api/session/retry)
retry_lastz/api/session/undo)	undo_lastrF  r  )rC  rD  onceresolve_all)r  rG  z/api/btwz/api/backgroundz	/api/goal/api/chat/startrL  z	/api/chatz/api/chat/steer)_handle_chat_steerz/api/terminal/startz/api/terminal/inputz/api/terminal/resizez/api/terminal/closez/api/crons/creater  z/api/crons/updatez/api/crons/deleter  z/api/crons/pausez/api/crons/resumez/api/git/stagez/api/git/unstagez/api/git/discardz/api/git/commit-messagez /api/git/commit-message-selectedz/api/git/commitz/api/git/commit-selectedz/api/git/fetchfetchz/api/git/pullpullz/api/git/pushpushz/api/git/checkoutz/api/git/stash-checkoutz/api/file/deletez/api/file/savez/api/file/createz/api/file/renamez/api/file/create-dirz/api/file/revealz/api/file/pathz/api/file/open-vscodez/api/workspaces/addz/api/workspaces/removez/api/workspaces/renamez/api/workspaces/reorderz/api/approval/respondz/api/clarify/respondz/api/commands/exec)execute_plugin_commandcommandzcommand is requiredr  zPlugin command not foundz/api/skills/savez/api/skills/deletez/api/skills/togglez/api/memory/writez/api/profile/switchname is required)switch_profile_validate_profile_name)build_profile_cookierC   )process_wide)invalidate_models_cachez
Set-Cookier  z/api/profile/createz^[a-z0-9][a-z0-9_-]{0,63}$zKInvalid profile name: lowercase letters, numbers, hyphens, underscores only
clone_fromzInvalid clone_from namer,  r7  )r  r  z,base_url must start with http:// or https://)create_profile_apiclone_config)r  r  r,  re  r7  r5  )r  rk  z/api/profile/delete)delete_profile_apir  r$  )create_sessionr  r  set_auth_cookier  r  r  _set_password_passwordless_clear_passwordr&  u   HERMES_WEBUI_PASSWORD env var is set — it overrides the settings password. Unset the env var and restart the server before changing the password here.)r  r  zSPasskey support is disabled. Enable HERMES_WEBUI_PASSKEY before going passwordless.z-Register a passkey before going passwordless.)clear_credentialsr%  r  r  auth_just_enabled   ensure_asciiindentr   r  application/json; charset=utf-8r  r  r  z/api/onboarding/oauth/start)r  HERMES_WEBUI_ONBOARDING_OPENzX-Forwarded-Forr  z	X-Real-IPzOnboarding OAuth is only available from local networks when auth is not enabled. To bypass this on a remote server, set HERMES_WEBUI_ONBOARDING_OPEN=1.z/api/onboarding/oauth/cancelz/api/onboarding/setupzOnboarding setup is only available from local networks when auth is not enabled. To bypass this on a remote server, set HERMES_WEBUI_ONBOARDING_OPEN=1.z/api/onboarding/completez/api/onboarding/probezOnboarding probe is only available from local networks when auth is not enabled. To bypass this on a remote server, set HERMES_WEBUI_ONBOARDING_OPEN=1.zprobe failed: z/api/session/pinc                 t    h | ]5}t          |d d          t          |dd          $t          |dd          6S )r=  Fr>  r5   N)rD   )r   existings     r   r   zhandle_post.<locals>.<setcomp>4  s]     $ $ $AI!(He<<$EST\^hjoEpEp$xt<<$ $ $r   c              3   d   K   | ]+\  }}t          |d d          t          |dd          '|V  ,dS )r=  Fr>  Nr   )r   r   r  s      r   rx   zhandle_post.<locals>.<genexpr>>  sb       " ")Cx599"BI(T^`eBfBf"" " " " " "r   pinned_sessions_limitrm   zUp to z: sessions can be pinned. Unpin one before pinning another.session_pinz/api/session/archiver;  z9Read-only imported sessions cannot be archived from WebUIr;  r  )r5   r  r<  r  r  r  r  r~  r%  r  r  r<  r9  r;  r:  r7  r6  rF  )rk  r  r  session_archivez/api/session/mover  c              3   4   K   | ]}|d          k    |V  dS r?  Nr   )r   rw   
target_pids     r   rx   zhandle_post.<locals>.<genexpr>  s1      MMqq*/L/L/L/L/L/LMMr   zProject not foundsession_movez/api/projects/creater/   r  colorz^#[0-9a-fA-F]{3,8}$zInvalid color format)r?  r   r  rk  r  )r  projectz/api/projects/renamec              3   @   K   | ]}|d          d          k    |V  dS r  r   r   rw   r   s     r   rx   zhandle_post.<locals>.<genexpr>  6      JJ1AlOtL7I$I$IQ$I$I$I$IJJr   z/api/projects/deletec              3   @   K   | ]}|d          d          k    |V  dS r  r   r  s     r   rx   zhandle_post.<locals>.<genexpr>  r  r   c                 8    g | ]}|d          d          k    |S )r?  r   r  s     r   r{   zhandle_post.<locals>.<listcomp>  s,    QQQ!1\?d<>P+P+PA+P+P+Pr   r   zFailed to update session %sz/Failed to load session index for project unlinkz/api/session/importz/api/updates/applyr  )r  r  z!target must be "webui" or "agent")apply_updatez/api/updates/force)apply_force_updatez/api/updates/summary)summarize_update_payloadupdatesuser_promptrF   c                 r   ddl m} |                                pd}|                    |dt                    5  ddlm}m}m} d| dd	|dg} | |                      \  }}	}
d }	 dd
l	m
} ddlm}  |||	          }|                    d          }|	s|                    d          }	|
s|                    d          }
n2# t          $ r%}t                              d|           Y d }~nd }~ww xY wt!          |	t"                    r/|	                    d          r ||	          \  }}|s|r|}|
s|r|}
|	||
|d}	 ddlm}  |d|          \  }}|g|re|j        j                            ||          }t#          |j        d         j        j        pd                                          cd d d            S n2# t          $ r%}t                              d|           Y d }~nd }~ww xY wddlm}  |||	|
|ddg dt=          j                    j         d d                    }|!                    || g dt=          j                    j         d d                    }t#          |                    d           pd                                          cd d d            S # 1 swxY w Y   d S )!Nr   r  rC   zupdate summarylogger_override)get_effective_default_modelresolve_model_provider"resolve_custom_provider_connectionsystemr  r   user0resolve_runtime_provider_with_anthropic_env_lockresolve_runtime_provider	requestedre  r  r,  z5update summary runtime provider resolution failed: %scustom:r  r  r,  re  get_text_auxiliary_clientcompressionmain_runtimer  r  rI   zEupdate summary auxiliary model failed; falling back to main model: %sAIAgentr  Tzupdates-summary-   r  r  r,  re  r6  
quiet_moder]  r5   user_messagesystem_messageconversation_historytask_idr  )"r  r  r  !profile_env_for_background_workerr   r`  r  r  r  	api.oauthr  hermes_cli.runtime_providerr  r?   r[   r   r=   r   r   agent.auxiliary_clientr  chatcompletionscreatechoicesr   r   r   	run_agentr  rp  rq  rr  run_conversation)rm  r  profiles_apir`  r  r  r  r  _main_model_main_provider_main_base_url_main_api_keyr  r  _rtr  _cp_key_cp_baser  r  
aux_client	aux_modelrg  r  r  r   s                             r   _llm_update_summaryz(handle_post.<locals>._llm_update_summary0  s   444444)AACCPyN??  & @   UG UG
          &-@@#<<
 ?U>TUpUpUrUr>s>s;^^ $^ZZZZZZTTTTTTJJ0"0  C %(GGI$6$6M) =),)<)<) =),)<)<  ^ ^ ^LL!XZ\]]]]]]]]^nc22 2~7P7PQZ7[7[ 2(J(J>(Z(Z%GX( 0W 0(/) 2h 2)1 !/( .,	   nPPPPPP -F,E%%1- - -)J	 "-)-#-?#>#E#E"+%- $F $ $  #8#3A#6#>#F#L"MMSSUUUG UG UG UG UG UG UG UG@ ! n n nLL!hjlmmmmmmmmn .-----%++)$#%'H$*,,2B2A22FHH	 	 	 //!,#0)+Etz||/?/CEE	 0   6::&677=2>>DDFFkUG UG UG UG UG UG UG UG UG UG UG UG UG UG UG UG UG UGsi   .J,)ACJ,
C5C0+J,0C55AJ,A2GJ,
G3G.)J,.G33B,J,,J03J0)llm_callbackr  z/api/session/import_clir  )verify_passwordr  r  r  )_check_login_rate_record_login_attemptzAuth not enabled)r  r   z)Too many attempts. Try again in a minute.r  passwordr    application/jsonr  )r  r  )PasskeyErrorauthentication_optionszaPasskey support is disabled. Set HERMES_WEBUI_PASSKEY=1 or webui_passkey_enabled: true to enable.)r  	publicKeyr  )r  r  r  r  )r	  finish_loginzPasskey support is disabled.z"/api/auth/passkey/register/options)registration_optionsz/api/auth/passkey/register)r	  finish_registrationr  credentialsz/api/auth/passkey/delete)r  r  )r	  delete_credentialr  r|  r   c              3   J   K   | ]}|                     d           k    V  dS r0  r   )r   r  credential_ids     r   rx   zhandle_post.<locals>.<genexpr>  s4      FsFshiquuT{{VcGcFsFsFsFsFsFsr   z@Set a password or disable auth before removing the last passkey.z/api/auth/passkeys)r  r   z/api/auth/logout)clear_auth_cookieinvalidate_sessionr  z/api/rollback/restorezrequest body is requiredr  z%workspace and checkpoint are required)restore_checkpointzrollback/restore failedr   (2  r/  r  r    r   r  r  r  r  r  r(  r  r  r)  r*  r+  r  r  r)  r[   r  rO  r  r  r?   r   r  rR  r8  r  r  save_dashboard_configrh   r&  r   r  r$  r  r   r   r  rT  r  rp  api.session_lifecyclerV  r`  rW  rX  r   r  r   r  r  r_  r`  rp  rq  rr  r  r<  r  r5  r@  r  r  r?  rk  r  r  r  r\  r@   rK  r  r  r5   ra  ro   r  rb  rJ  r  r  rc  r5  r6  r  r  r  r2  reload
api.routesroutesr   _handle_sessions_cleanupr%  rd  r   r  r#  r[  r=   r>   r   r  ra  r  r]  r  r   rN   ru  rl  r\  r4  r7  r{  api.terminalr}  r  r  r  r+  ru  r  r   rP  re   rf   unlinkr   r  
api.uploadr  shutilrmtreer  r  rG  r  r  r  r  r  r  r  r  r  _handle_session_compress_start_handle_session_compress_handle_conversation_rounds_handle_handoff_summaryr  r  rH  tools.approvalrC  rD  rG  rI  _handle_btw_handle_background_handle_goal_command_handle_chat_start_handle_chat_syncapi.streamingr  _handle_terminal_start_handle_terminal_input_handle_terminal_resize_handle_terminal_closerZ   r  _handle_cron_create_handle_cron_update_handle_cron_delete_handle_cron_run_handle_cron_pause_handle_cron_resume_handle_git_stage_handle_git_unstage_handle_git_discard_handle_git_commit_message#_handle_git_commit_message_selected_handle_git_commit_handle_git_commit_selected_handle_git_remote_action_handle_git_checkout_handle_git_stash_checkout_handle_file_delete_handle_file_save_handle_file_create_handle_file_rename_handle_create_dir_handle_file_reveal_handle_file_path_handle_file_open_vscode_handle_workspace_add_handle_workspace_remove_handle_workspace_rename_handle_workspace_reorder_handle_approval_respond_handle_clarify_respondr  r  _handle_skill_save_handle_skill_delete_handle_skill_toggle_handle_memory_writer  r  api.helpersr  r  FileNotFoundErrorr  r  r  FileExistsErrorr  r  r  r  r  r  r  r]   r^   r  r  r  r  r  r  r  r  r  r  r*  r  r  r  	ipaddressr  r   r  
ip_addressis_loopback
is_privater=  r;  r7  r9  r:  r  r   r	  r  discardr  r=  r  r  r~  r%  r  r  r<  r9  r;  r:  r7  r6  r  r>  r   r  nextr  rE   r  r  rz   r  r   _handle_session_importr  r  r  r  _handle_session_import_clir  r  r  r	  r
  r  r  r  r  r  r   r  r  r  r  )r6  r7  rM  rO  r   rR  r  r  r<  r   rY  worktree_requestedrT  base_workspacer  r5  rU  rV  rW  rX  
prev_agent_cachedr   r   rA   copied_sessionr_  r`  r  rc  r  re  rf  rg  flagr  _models_routesr   rn  _reload_cfg2	_get_cfg2_cfg2r=  r>  r-  rn   rr  rN   rv  r.  rw  _MAX_DRAFT_TEXT_MAX_DRAFT_FILESold_ws	old_modelold_providernew_wsr{  r}  r  r  cli_meta_for_deleter  r   rw   r  r  keepr  r4   r  custom_titler  r  source_messagesforked_messagesbranch_titlesource_titlerv  r  r  r  _p_lr  r  r  r  r  r  r  r  r  r  r,  r7  r  r  r  r  r  r  r  auth_enabled_beforecurrent_cookielogged_in_beforerequested_passwordrequested_passwordlessrequested_clear_passwordr  r  r  savedauth_enabled_afterr  logged_in_after
new_cookieresponse_body_osrU  _xff_xri_rawaddris_local_ip_strpin_requestedpersisted_pinned_ids
pinned_idsr  r2  r  r`  r  r  r  projr  r1  r  r  r  r  r  r  r  r  	client_ipr  r  r	  r
  r  r  r  r  r  credsr  r  r  r  r   r  r  s                                                                                                                                                                      @@@r   handle_postr  i  sh   )&&+fMMMD{''' 	%JJ|$$$	%g.. t 
  

6V[)) +g2F2F 	Ww(=g(F(FGPSTTT t  {o%%((({m##W%%%{+++$W---{''' ))){... 	1JJ/000'1KG1T1TUUU  

;!!    	KKMMM
 {999EEEEEE--kI^I`I`aaa&

70C0C)LMMMM{n-- 888888##GVT::U??+GVVDDDt{---''''''	/g<<TBBCCCC 	/ 	/ 	/S#......... 	/ 	/ 	/;<<<S#.........	/ t{(((	(QUQYQYZeQfQfp5dhh{6K6KLLMMMlpII:& 	( 	( 	(wA''''''''	(HHZ  D( W488J''((..006688<VV 	  	SSGGGGGG!*% Z%()BCUCWCW)X)X%Y%YN = =n M M)&1		z* 8 8 87CFF3777777777 S S S  !KLLL7$E!$E$EcRRRRRRRRRS !BHHWHH%&&!
 !
~ ((#455 	l
lGGGGGGTTTTTTTT!
- 0 0155oFFG 0%,QZ
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &%oZHHHHH l l lJOfjkkkkkl)HHY''/4xx--5'
 
 
  	8(7779aiikkZ4L&LMNNN{...>	(((<((C >7$<===l3''G E7$7DDDD %   :<<+CRC00 }2
i??	
 "++ mm  '55 w'7888  =);<<< u  #--   !" %11#$ &33%&  '55'0 $//12 ")2Dd!K!K!K34  'w0@$GGG56 ")2Dd!K!K!K78  9;;;9:  9;;;;N@  1 16D23$^%>???(mml22$%0000 (mml221 1 1 1 1 1 1 1 1 1 1 1 1 1 1 !!!()<===Wy.*@*@*B*BjR`RiEj*jklll 	( 	( 	(wA''''''''	( {***	-W6txx7H7HIIJJJ 	( 	( 	(wA'''''''' 	- 	- 	-wA,,,,,,,,	- {&&&DHHW%%+,,2244488F##)r**0022txx
++5v66<<>>DHHW%%+,,2244K666666:"5"5dHe"L"LMMM : : :7CHHS999999999:F??:":5"A"ABBB : : :7CHHS999999999:75e55cBBBB {&&&xx
++1r88::@@BB((9%% 	8w 6777'll((**2dG!+w77zz$ 	Fw

7O D DEEE&!!!{---xx
++1r88::@@BB 	8w 6777$[11zz$ 	Fw

7O D DEEE&!!!{&&&	-hhy))GXXh''F"7||))++1133666W&;D&A&ABBB888W&;E&B&BCCC7$Yg$Y$Y$YZZZ!"6v">">???w NOOO 	( 	( 	(wA'''''''' 	- 	- 	-wA,,,,,,,,	- {)))))))))!!! 	%$$$$$%1!/!/T|DDEEE{---'GGGG{:::'FFFF{+++	(D,0000 	( 	( 	(wA''''''''	(	:D.//A4T,5GKKAA 	: 	: 	:w 3S99999	:$T,%788 	 	$w-((..00"5CAGFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	%%56669aiikk2333{,,,	(D,'''' 	( 	( 	(wA''''''''	(w >???< F|!!##	:C  A4S!<<AA 	: 	: 	:w 3S99999	:  	$@@@@@@LNNN::::::IKKE		'2..I )or B B/66 $FW:W:WMTMMMs   &d+E%&& $?B77R599Xr;R;RS99V$$ ;LL!9%-!9!9:::99W%% =LL!;5>!;!;<<<"9"9e"9"9"999U$S)) 	 	$(2DDdAMFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 amvVVWWW{---	
	(D,'''' 	( 	( 	(wA''''''''	(< 88J''h-- QX Q7$OPPPBBBBBBB O7$MNNN	:C  AA 	: 	: 	:w 3S99999	:$S)) 	 	!)AFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 1;MNNOOO{*** ?e##V\**E6<lJ%))L2$//22C C7$<cBBB>$$ > > >7$7=====>A/44:EWw.///	(D,'''' 	( 	( 	(wA''''''''	(< xx!!
 !JtS$9$9DdC   	*SYY%@%@(()DZt%<%<EeT"" 	-s5zz4D'D'D+++,E	:C  AA 	: 	: 	:w 3S99999	:$S)) 	< 	<A/44:E $f !&g$A
 FFEdF;;;	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 0@AABBB{+++	(D,'''' 	( 	( 	(wA''''''''	(	:D.//AA 	: 	: 	:w 3S99999	:K,,Aw--	q"2D99	(2488K3U3UVVWWFF 	( 	( 	(wA''''''''	($T,%788 	 	 AK$"2d":":"CHHWag..2Bd2J2JDHH-...PTA/66# #x
 $#AG#+ 	R((C7B0G0G0M2,N,NNN<-2..#gaAQSU6V6V6\Z\2]2]]]'P7D11#3T::( (A$ *+A&+,A(??????((l);<<<FFHHH1	 	 	 	 	 	 	 	 	 	 	 	 	 	 	2 v|FLb 1 111Z777777tL12222 Z Z ZXYYYYYZ6"""9aiikkZ4L&LMNNN{444hh|R(( 	U*S#.. 	Uciikk 	Uw GPSTTTTiikkMMMMMMM 	;w 4c:::	ACt444AA 	A 	A 	Aw 3C@@@@@@	ATXXgu--..		BAAAAAA00%@@@FWf%%% 	6 	6 	6wC555555555 	B 	B 	BGMMMw 4 4SAAAAAAAAA	B {+++hh|R(( 	:w 8999MMMMMMM 	;w 4c::::3??"";// 	aw Z\_```7<<EcJJ 	$ 	$Ld###	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	433333S!!!	;#}}},5577AMM+-//0000 	; 	; 	;w 4c:::::	;	@HHH%%%MM+&&--->>>> 	@ 	@ 	@LL;Q?????	@	_$S)))) 	_ 	_ 	_LLI3Y]L^^^^^	_	W::::::M11#66dKKKKK 	W 	W 	WLLPRUVVVVV	W & 	/ 	/#C...	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/	[333333N3 	[ 	[ 	[LLTVYZZZZZ	[ $ 	EE999999""3'''' E E E>DDDDDE$%56664;):;<<<{***	(D,'''' 	( 	( 	(wA''''''''	(	:D.//AA 	: 	: 	:w 3S99999	:< $S)) 	 	AJAL AGFFHHH		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	433333S!!!!))++>>???{---	(D,'''' 	( 	( 	(wA''''''''	(88L!!)w GHHH	:D.//AA 	: 	: 	:w 3S99999	:4%&&$T,%788 	 	ETE*AJ-EEEEEE)B)B1:)N)N&& - - -),&&&-FFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 DQYY[[J
;S-STT
 
 	
 {+++
	(D,'''' 	( 	( 	(wA''''''''	(
 $|,c22 	?w =>>>	: l!344FF 	: 	: 	:w 3S99999	: XXl++
!E __

	* E E E7$CDDDDDE A~~7$EFFFxx(( 	B|,,2244SbS9ATL
	KKMMMM 	 	 	D	FklrFsFs{/0ABBBy{;FCCmGcdlGmGmFZb/0ABBB`b $-(4-0FFFfo+,, 	
 !-kzk:OO"?33O  	4'LL!<5:L*333L &,FIt44$$/!
 
 
  	- 	-*0HV&' !2333h--,.. e,,,, h--,..	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-  	;KKMMM()9::: +!!'!2
 
   	 {333-gt<<<{---'666{888*7D999{444&w555{***	(D,'''' 	( 	( 	(wA''''''''	(	1222222Z\ 233FWtT4V4555 	: 	: 	:w 3S99999 	1 	1 	1WwA/00000000	1 {)))	(D,'''' 	( 	( 	(wA''''''''	(	1111111YtL122FWtT4V4555 	: 	: 	:w 3S99999 	1 	1 	1WwA/00000000	1 {)))	(D,'''' 	( 	( 	(wA''''''''	(< txx	40011 	&$$$FFFFFFFF & &FF3%%%& & & & & & & & & & & & & & &   $S&dCCCCC %%%w??@@@{j  7D))){'''!'4000{k!!#GT222{'''!'4d;;;;{k!! $///{'''444444!!'4000{+++%gt444{+++%gt444{,,,&w555{+++%gt444
 {)))555555!!## 	6 	6&w55	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 {)))555555!!## 	6 	6&w55	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 {)))555555!!## 	6 	6&w55	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 {&&&555555!!## 	3 	3#GT22	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 {(((555555!!## 	5 	5%gt44	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 {)))555555!!## 	6 	6&w55	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 {&&& $///{((("7D111{((("7D111{///)'4888{88827DAAA{'''!'4000{000*7D999{&&&($@@@{o%%($???{o%%($???{)))#GT222{///)'4888 {((("7D111{&&& $///{((("7D111{((("7D111{,,,!'4000{((("7D111{&&& $///{---'666 {+++$Wd333{...'666{...'666{///($777 {---'666 {,,,&w555 {***777777dhhy"--344::<< 	7w 5666	9Wx)?)?)H)HIJJJ 	- 	- 	-wA,,,,,,,, 	A 	A 	Aw :C@@@@@ 	9 	9 	9w 2 2C88888888	9 {(((!'4000{***#GT222{***#GT222 {)))#GT222 {+++xx##))++ 	4w 2333	-KKKKKKKK888888y  &&t,,, $^Du===F ;:::::##%%%Wf224885     -. 	9 	9 	9w 2 2C88888888 	- 	- 	-wA,,,,,,,,	- {+++xx##))++ 	4w 2333sy6== 	]   XXl++
!Z..00J39:JGG ?7$=>>>7;xx
7K7KU488J++11333QU59XXi5H5HR$((9b))//111dAE/AZAZd"55;;===`dCG88L\C]C]g"2B77==???cg 	PH//0GHH 	Pw NOOO	(777777''%!$((>5"A"ABB!+-  F WTf==>>>O\: 	( 	( 	(wA''''''''	( {+++xx##))++ 	4w 2333		-OOOOOOOO""4(((''--FWf%%%-. 	4 	4 	4w 2 233333333 	- 	- 	-wA,,,,,,,,	- {o%%	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
  #D$4 5 5 ;BBDDPD-o//%g.. Q>>.3Q3QRR!txx00#66 6"--3355
 
 "&dhh&F&F!G!G#'1B(C(C(]G]#^#^ ! 	+&*D"#  	!9 	y0"55;;== b	   " 	 >>>>>>;;;;;;0022 @7$y{~))++ Z7$SUXYYYZ% 	 666666d##		/4(((,_.. Q#5Q>Q:Q
 
 +
 	#%5 	#'))J"O 2n,k%6!" 	%We$$$
5uQGGGNNwWWc"""N,MNNN,c#m2D2D.E.EFFFOZ888,,,'"""M***t{333,,,,,,   	D4R)S)S 	D!**+<bAAGGLLQOUUWW**;;;AACC-a0 ++D,@D,@DAA+>t ! ! ! ! D7  %~  @C  D  D  D	-W9$??P_akOlmmmm 	( 	( 	(wA'''''''' 	- 	- 	-wA,,,,,,,,	- {444	(W:4@@Q`blPmnnnn 	( 	( 	(wA''''''''	( {--- 	-,,,,,   	D4R)S)S 	D	!**+<bAAGGLLQOUUWW**;;;AACC-a0.$.$ ++G44+>t ! ! ! ! D7  %~  @C  D  D  D	-W4T::;;; 	( 	( 	(wA'''''''' 	- 	- 	-wA,,,,,,,,	- {000-//000{--- 	-,,,,,   	D4R)S)S 	D!**+<bAAGGLLQOUUWW**;;;AACC-a0.$.$ ++G44+>t ! ! ! ! D7  %~  @C  D  D  D
''
339r::@@BBHHJJ
''
339r::tzr&&y117R88>>@@HD	;W5h'RRSSS 	; 	; 	;w 4 4 4c::::::::	; {(((	(D,'''' 	( 	( 	(wA''''''''	(	:D.//A4T,5GKKAA 	: 	: 	:w 3S99999	:TXXh5566  	He!<!< 	$ $MY^^$ $ $      
 !!566
!! " "-5^-=-=" " "    ""4#5666(+MOO,?,?@WYZ,[,[,`_`(a(a%z??&;;;w  )C1F  )C  )C  )C  EH  I  I               "  #                             $ )l);<<                 )l);<<  (               	%]333!))++>>??? {,,,	(D,'''' 	( 	( 	(wA''''''''	(< ?	6C  A
 q1599 &L%%9"3--' & &$%HSM& & & & & & & & & & & & & & & 3	6 3	6 3	63C88H >7$7=====||K(( f7$_adeeeee+H55 -6"",,w//k:>VWZ>[>[]j3k3k022",,w//<9'||L99'||L99   $( '||L99'||L99WX\\,=W=W#+<<0@#A#A !)n!=!=$LL33	$LL33	&ll;77&ll;77 (] ; ;%\\*55
..../44 Bw(;SAAAAA&LL))LZm-L-LLL))6Y$LL33'||L99'||L99   $( '||L99'||L99WX\\,=W=W#+<<0@#A#A !)n!=!=$LL33	$LL33	&ll;77&ll;77 (] ; ;%\\*55
g3	6h %S)) 	+ 	+dhhz48899AJFFEF***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	%%6777!))++__A[\]A^A^_``` {)))	(D,'''' 	( 	( 	(wA''''''''	(	:D.//AA 	: 	: 	:w 3S99999	: XXl++3t
 
	><<<<<<4466NMMMMMOOMMM F  >7$7==="6::i#8#8.II >7$7===$T,%788 	 	%ALFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	%^444!))++>>??? {,,,	(D&!!!! 	( 	( 	(wA''''''''	(888888F|!!##DSD) 	1w000!! 	8#95AA 	8w 6777 ??*,,*3B3/..00=I)++
 
 	h$77888{,,,	(D,//// 	( 	( 	(wA''''''''	(888888 ??JJJJJJJD
 
  	:w 3S9990022txx	22NCC 	:w 3S999F|))++DSD1Vd??ME <YSY'=uEE <7$:;;;!DMh$77888{,,,	(D,'''' 	( 	( 	(wA''''''''	(888888 ??JJJJJJJD
 
  	:w 3S9990022txx	22NCC 	:w 3S999QQQQxQQQh$&& 	PP
#5#?#Q#Q#QRR" a aEyy..$|2DDDa +E,,? @ @A+/ALFFHHHH( a a a"LL)F		R^H_H_`````a Ea  P P PNOOOOOP4,''' {+++%gt444 {***(B''+++w CDDD,,,,,,,,v..///{***(B''+++w CDDD222222,,V44555{,,,888888)3D$)?)?G$((9%%%R'1$'='=G(###4Z	Gs Z	G Z	G Z	G Z	G Z	G Z	Gx 227I\eklllmmm {///)'4888 {'''	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	FEEEEEEE   	KWT6HIIJJJ*1-	  ++ 	EF   
 88J++x(( 	9!!),,,w 2C888#^%%
z4,''..00c"""N,>???,c#d))nn===OZ888'""",,,D!!!t{111KKKKKKKKEEEEEEEE,,.. 	ZWw  )L  M  VY  Z  Z  Z  Z   	IWw(:;CHHHH	4WT8N8Nw8W8WXXYYY 	4 	4 	4wAs333333333	4 {///llllllllllllEEEEEEEE;;;;;;;;,,.. 	UWw(FGPSTTTT   	IWw(:;CHHHH*1-	  ++ 	bWw(ST]`aaaa	4Lw'''' 	4 	4 	4!!),,,wAs333333333	4 $^%%
c"""N,>???OZ888'""",,,DJd|44;;==>>>t{:::::::::555555,,.. 	UWw(FGPSTTTT4H4H4Q4QRRSSS{222::::::ZZZZZZZZZZ,,.. 	UWw(FGPSTTTT	4((w77F$:$:$<$<F=!Wf%%% 	4 	4 	4wAs333333333	4 {000MMMMMMMMXXXXXXXXXX,,.. 	UWw(FGPSTTTT	4 4"55M**,,E  ""*s5zzQ3FsFsFsFsmrFsFsFsCsCs7$fhklllW//>>??? 	4 	4 	4wAs333333333	4 {***::::::777777,,.. 	EWbdCCDDD=*@*@*B*BCDDD{(((PPPPPPPPPP!\'**
 	+z***z4,''..00c"""N,>???,c#d))nn===OZ888'"""'"""D!!!t {--- 	<w :;;;HH["--	XXlB//
 	I
 	Iw GHHH	4777777W00JGGHHH 	( 	( 	(wA'''''''' 	4 	4 	46777wAs333333333	4 5sG  A. .B C= =DG( ("H
;#K 
M)LM9MM/AN6 6O.O)#O.)O.AR T,S
TT.TTT*W < V(W (V,,W /V,0W 'W+*W+9&c  'c D c (A8a, c ,a00c 3a04Ac 
c9c4.c94c9/d8 8
fe$f$f1fffj( (
k2kkk%l 
l5l0*l50l55A?w 5 w w *w 	w 
x:#x?x:x:x5/x:5x:+{= =
|.|)#|.)|.2+} }<;}<A++/2/@6AA A
AA8AAA3A-AA8A3AA8B2AC CAC0C/AC0I  AJJAJJAJJ>AK K
AL KAK;K5AL K;AL M3AN NAN!N AN!N3AOOAOO"AOQ#AQ3 Q3ARRARR:AS S
AS<SAS7S1AS<S7AS<WAW WAW:W9AW:XA AYYAYYAYZAZ Z
A[
Z#A[Z?A[
[A[
[A[$ [$A\\A\\95A]/ ]/
A^ ]9A^^A^ ^A^ ^8EAddAddAdd<Ae e$Ae;e:Ae;iAi+ i+Aj
j	Aj
j1"Ak k
AmkAlk<AmlAml9AmmAmmAmpAp0p0Ap4p7Ap4qAAr rAr1r0Ar1r5?As5 s5%AttAtt!At2 t2'AuuAuu &Av v%Av/v.Av/v:AwwAw!w$Aw!w)Aw; w;%Ax#x"Ax#x)Ax; x;%Ay#y"Ay#zAz' z'
A{z1A{{A{{A{{A{2 {2A||A||**A} } A}$}'A}$~.A~? ~?
A0	A+%A0+A0@B@/ @/BAABAA;BC$BBB-B,BC$B-BCB>BC$C BCCBC$C$BC(C+BC(D+BD< D<
BE-EBE(E"BE-E(BE-FBF2 F2BGGBGG+BG< G<!BH HBH I<BJ J
BJJBJNA8BPPBPP BPS#BS4 S4
BT%S>BT TBT%T BT%T)*BU UBV#U1	BV#U:BVVBV#VBV#V2BW W
BW4WBW/W)BW4W/BW4W8*BX# X#BY2Y 	BY2Y	BY-Y'BY2Y-BY2ZBZ Z
B[ZBZ?Z9B[Z?B[\
B\> \B\2\&B\> \2B\6\6B\> \9B\6\:B\> \>
B]]
B]b;BccBcc Bcc?BddBd!d$Bd!eBe!e!Be%e(Be%fBf%f%Bf)f,Bf)gBg)g)Bg-g0Bg-hBh-h-Bh1h4Bh1u0Bv v
BxvBv9v3Bxv9Bxw	Bxw#Bxx BxxBx{AB|+ |+B~|=B} }B~} B~}-B~~
B~~B~FACG GCHG5CHHCHHCHI'.CJ JCK?J(CK
KCK?K
CK?KCK:K4CK?K:CK?Y8B*C\# \#C\2\1C\2]
$C]/ ]/
C_]9C^^C_^C_^(C__C__C__ $C` `
C`6`C`1`+C`6`1C`6a6B,Cd# d#Cd2d1Cd2e
Ce( e(
Cg	e2CffCg	fCg	f!Cgf>Cg	gCg	h2B,Ck kCk.k-Ck.n1Co o
Co:oCo5o/Co:o5Co:pCp p
Cqp&CqqCqqCqq+Cq= q=CrrCrs7B?CwwCwwCwwCww7CxxCxxCxx9Cy"y"Cy&y)Cy&z0C{ {
C{2{C{-{'C{2{-C{2{>AC}/ }C}"}C}/ }"C}&}&C}/ })C}&}*C}/ }/-DN#~'DN#HDN#GGDN#N"DN#N5ADPPDPP	DPQ DQ1 Q1
DR"Q;DRRDR"RDR"R&DR< R<DSSDSVDV:V:DV>WDV>XDX X
DY
X#DYX?DY
YDY
]#D]5 ]5
D^&]?D^!^D^&^!D^&cDc c
Dd	c"Ddc>Dd	dDd	g
ADj h0DiiDj i9DjjDj jDjjDj j%Dj5j4Dj5y)Dz zDz4zDz/z)Dz4z/Dz4}D}! }!D~}&*D~~D~~D~C7)ED! D!EED&EE
EEEE
EEFA;EH* HEH* H*EIH/EIIEIIEIP,"EQ Q
ESQEQ;Q5ESQ;ESR9ESSESSESc                    t          |           s!t          | dt          |           id          S t          |           }|j                            d          r-|j        t          d          d         }t          | ||          S |j                            d          r*ddlm	}  || ||          }|d	u rt          | |d
          S dS d	S )z@Handle all PATCH routes. Returns True if handled, False for 404.r   rM  r5  /api/mcp/servers/Nr  r   )handle_kanban_patchFPATCHT)r  r(  r  r)  r    r   ro   _handle_mcp_server_toggler  r  r8  )r6  r7  r   r   r  r   s         r   handle_patchr  .  s    w Q7$9'$B$BCCPPPPWD{122 >{3233445($==={n-- 999999$$Wfd;;U??+GVWEEEt5r   c                    t          |           s!t          | dt          |           id          S t          |           }|j                            d          r,|j        t          d          d         }t          | |          S |j                            d          r*ddlm	}  || ||          }|d	u rt          | |d
          S dS d	S )zAHandle all DELETE routes. Returns True if handled, False for 404.r   rM  r5  r  Nr  r   )handle_kanban_deleteFDELETET)r  r(  r  r)  r    r   ro   _handle_mcp_server_deleter  r  r8  )r6  r7  r   r   r  r   s         r   handle_deleter  @  s    w Q7$9'$B$BCCPPPPWD{122 8{3233445($777{n-- ::::::%%gvt<<U??+GVXFFFt5r   c                     t          |           st          | ddid          S t          |           }|j                            d          r-|j        t          d          d         }t          | ||          S dS )z>Handle all PUT routes. Returns True if handled, False for 404.r   r  rM  r5  r  NF)r  r(  r)  r    r   ro   _handle_mcp_server_update)r6  r7  r   r   s       r   
handle_putr  R  s    w R7$CDSQQQQWD{122 >{3233445($===5r   text/cssapplication/javascript	text/htmlimage/svg+xml	image/png
image/jpegr  	image/gif
image/webpz	font/woffz
font/woff2)cssjsr  svgpngjpgjpegicogifwebpwoffwoff2>   r  r  
text/plainr  r  >   r  r  r  r  r  r  _STATIC_CACHEc                 |   t          t                    j        j        dz                                  }|j        t          d          d          }||z                                  }	 |                    |           n$# t          $ r t          | ddid          cY S w xY w|	                                r|
                                st          | ddid          S |j                                        }t                              |                    d          d          }|t           v r| d	n|}|                                }|j        |j        f}	t)          |          }
d x}x}}t*          5  t,                              |
          }|r|d
         |	k    r|\  }}}}d d d            n# 1 swxY w Y   ||                                }d|	d
         dd|	d         dd}|t0          v r)t          |          dk    rt3          j        |d          nd }t*          5  |	|||ft,          |
<   d d d            n# 1 swxY w Y   t7          |j        d                              ddg          }t;          |d
                   }|rdnd}| j                            d          |k    ro|                     d           |                      d|           |                      d|           ||                      dd           | !                                 dS | j                            d          pd                                }|d uod|v }|r|n|}|                     d            |                      d!|           |                      d"t)          t          |                               |                      d|           |                      d|           ||                      dd           |r|                      d#d           | !                                 | j"        #                    |           dS )$Nr  r.  r   r  r4  r5  r$  r  z; charset=utf-8r   zW/"r  r#  r   r  r  r  )compresslevelT)keep_blank_valuesvrI   z#public, max-age=31536000, immutablezpublic, max-age=300zIf-None-Matchi0  ETagr  VaryzAccept-Encodinggzipr   r  r  zContent-Encoding)$r   r  r   re   r    ro   rf   rh   r(  rz   r   suffixr   _STATIC_MIMEr?   rd  _TEXT_MIME_TYPESr=  r  st_mtime_nsr   _STATIC_CACHE_LOCKr  r  _COMPRESSIBLE_MIMEr  compressr   rN   r  r  r  r  r  r  r  )r6  r7  r  r  static_filer  ct	ct_headerrA  sig	cache_keyrQ   gzetagr  r   version_valueshas_fingerprintcache_control
accept_encuse_gzipr   s                         r   r  r    s   >>(/(:CCEEK
+c*oo''
(C$--//K>,,,, > > >7K0======> >{':':'<'< >7K0====


"
"
$
$C			#**S//<	8	8B*,0@*@*@2&&&&bI 
				B:r~
&CK  IC"t	 & &""9-- 	&fQi3&&%AsB& & & & & & & & & & & & & & & {$$&&+SV+++A++++)))c#hhoo mCq1111 	   	< 	<(+S"d';M)$	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< fldCCCGGbTRRN>!,--O1@ 	#--"  ?++t33c"""FD)))O];;;>(9:::t/%%&788>BEEGGJ~6&J"6H"22sD#	222(#c$ii..999%%%777	~F$5666 8.777M4s6   (A> >BB30F//F36F3"H==IIc           
          t          |j                                      ddg          d         }|st          | d          S 	 t	          |          }n!# t
          $ r t          | dd          cY S w xY wt          |j                  }t          j	        |dd	          }| 
                    d
           |                     dd           |                     dd| d           |                     dt          t          |                    d                                         |                     dd           |                                  | j                            |                    d                     dS )Nr5   rI   r   r/  r0  r4  Fr  r  r   r  r  Content-Dispositionzattachment; filename="hermes-z.json"r  r   r  r  T)r   rN   r?   r&  r   r   r,  __dict__r  r  r  r  r   ro   r  r  r  r  )r6  r7  r   r   r  r   s         r   r  r    s   
6<
 
 
$
$\B4
8
8
;C 6745556 6 6 67/555556qz**DjE!<<<G#(IJJJJsJJJ   (#c'..2I2I.J.J*K*KLLL444Mw//0004s   A A10A1c                     t          | t                    r|                     d          nd}t          |t                    rd                    d |D                       S t          |pd          S )Nr   rI   r3  c              3      K   | ]U}t          |t                    r>|                    d           dk    0t          |                    dd                    V  VdS )r  r.  rI   Nr=   r>   r?   r   r  s     r   rx   z/_session_search_message_text.<locals>.<genexpr>  so       
 
$%%
 +/((6*:*:f*D*D $$%%*D*D*D*D
 
r   r=   r>   r?   ra  r  r   )r   r   s     r   _session_search_message_textr    s    (27D(A(AIgkk)$$$rG'4   
xx 
 

 
 
 
 
 	

 w}"r   |   c                    t          j        ddt          | pd                                                    }t          j        ddt          |pd                                                    }|r|sdS |                                                    |                                          }|dk     rdS t          dt          |pd                    }t          |          |k    r|S t          d|t          |          z
  dz            }t          d||z
            }t          t          |          |t          |          z   |z             }|dk    rB||k     r#||         dk    r|d	z  }||k     r||         dk    ||k    rt          d||z
            }|t          |          k     r||t          |          z   k    r9||d	z
           dk    r*|d	z  }||t          |          z   k    r||d	z
           dk    *||t          |          z   k    r0t          t          |          |t          |          z   |z             }|||                                         }	|dk    rd
|	z   }	|t          |          k     r|	d
z   }	|	S )N\s+r3  rI   r   r0   r  r[  r  r   r   )
r  subr   r   r   rZ  r  r  ro   r[  )
r.  rN   max_lenr  r\  r^  contextr  rp  excerpts
             r   _session_search_previewr    sw   S__55;;==J
vsC,,--3355A Q r





!
!!''))
,
,C
Qwwr"c'.S))**G
:'!!"wQ'A-..G3=!!E
c*oosSVV|g5
6
6Cqyyckkj/366QJE ckkj/366C<<3=))E
S__C#a&&L  Za%8C%?%?1HC C#a&&L  Za%8C%?%?#A,c*oosSVV|g'=>>Cs#))++Gqyy'/
S__E/Nr   c                    t          |j                  }|                    ddg          d                                                                         }|                    ddg          d         dk    }t          |                    ddg          d                   }|sg }t                      D ]f}t          |          }t          |                    d          t                    rt          |d                   |d<   |                    |           gt          | d	|i          S g }	t                      D ]}||                    d          pd                                v }
|
rgt          |d
          }t          |                    d          t                    rt          |d                   |d<   |	                    |           |r	 t          |d                   }|r|j        d |         n|j        }|D ]}t          |          }|t          |                                          v rt          |d
          }t!          ||          }|rt          |          |d<   t          |                    d          t                    rt          |d                   |d<   |	                    |            n# t"          t$          f$ r Y w xY wt          | |	|t'          |	          d          S )Nr\  rI   r   r   rJ   depth5r  r1  )
match_typer5   match_preview)r1  rN   r   )r   rN   r?   r   r   r  r  r>   r=   r   r-  r   r(  r   r  r  r  r   r[   ro   )r6  r7  rP   r\  content_searchr  safe_sessionsr   r  rJ  title_matchr3  r2  r  r  previews                   r   r  r    s   	&,		B
sRD!""$$**,,AVVIu--a0C7Nw&&q)**E 7 	' 	'A77D$((7++S11 < ,T'] ; ;W  &&&&:}5666G^^  AEE'NN0b77999 	g...D$((7++S11 < ,T'] ; ;WNN4    	"1\?3305Ht}VeV,,4= 
 
A4Q77ACFFLLNN**#A)<<<"9!Q"?"?" J4@4I4ID1%dhhw&7&7== H,8g,G,GDMt,,, + i(   	" W7QWNNOOOs   C0K		KKc           	         t          |j                  }|                    ddg          d         }|st          | d          S 	 t	          |          }|j        }n# t          $ rv 	 d }t                      D ]}|d         |k    r|} n|st          | dd          cY S |                    dd          }n## t          $ r t          | dd          cY cY S w xY wY nw xY w	 |                    dd	g          d         }t          t          |          |          }	t          | |	t          t          |          ||	          |d
          S # t          t          f$ r(}
t          | t          |
          d          cY d }
~
S d }
~
ww xY w)Nr5   rI   r   r/  r0  r4  r<  r    r$  )entries	signaturer    )r   rN   r?   r&  r   r<  r   rt  r[   r  r   r(  r   rS  rh   r+  )r6  r7  rP   r   r   r<  r  csrq   r  r   s              r   r  r  7  s   	&,		B
&&t
$
$Q
'C 674555:K		 : : :
	:H&((  l#s**!HE +  >7$7===== ["55II 	: 	: 	:w 3S9999999	: I:566&3%((+4	??H55"*4	??HgNN  
 
 	
 z* 5 5 57OA..444444445sa   A 
C'5B6CB65C6CCCCC A)E
 
FE>8F>Fc                     |r1| j                             d| d                    d                     t          | ||           d S )Nzid: r   r   )r  r  r  r,  )r6  r3   r  event_ids       r   _sse_with_idr  [  sS     A/8///66w??@@@%r   rP   c                     |                      dd g          d         }|dv rd S 	 t          dt          |                    S # t          t          f$ r Y dS w xY w)N	after_seqr   r#  )r?   r  r  r  rh   )rP   rQ   s     r   _parse_run_journal_after_seqr  a  sn    
&&tf
%
%a
(C
jt1c#hhz"   qqs   A AAr6   r  c           	      j   t          |          }|sdS t          t          |                    d          pd          ||          }|                    d          pg D ]d}t	          | |                    d          p|                    d          pd|                    d	          |                    d
                     e|                    d          sZt          t          |                    d          pd          ||          }|r$t	          | |d         |d	         |d
                    dS )NFr5   rI   )r  eventsr3   r  r   r   r  rU  T)r/  r0  r   r?   r  r1  )r6  r6   r  rS  r  r1  stales          r   _replay_run_journalr  k  sP   y))G uGKK%%+,,  G
 X&&," 
 
IIg@%))F"3"3@yIIi  IIj!!		
 	
 	
 	
 ;;z"" W'L))/R00
 
 

  	W%.%	2BE*DUVVV4r   c                 L   t          |j                  }|                    ddg          d         }t          j        |          }|	 |rt	          t          |                    nd}n# t          $ r d}Y nw xY w|st          | ddid          S |                     d	           | 	                    d
d           | 	                    dd           | 	                    dd           | 	                    dd           | 
                                 	 t          | |t          |                     n# t          $ r Y nw xY wdS t          |d          r|                                n|}|                     d	           | 	                    d
d           | 	                    dd           | 	                    dd           | 	                    dd           | 
                                 	 	 	 |                    t                     \  }}nH# t"          j        $ r6 | j                            d           | j                                         Y ew xY wt-          j        |          }	|	rt/          | |||	           nt1          | ||           |dv rnn# t          $ r Y nw xY w||ur7t          |d          r'	 |                    |           nR# t          $ r Y nFw xY wnA# ||ur7t          |d          r(	 |                    |           w # t          $ r Y w w xY ww w xY wdS )Nr6   rI   r   Fr   zstream not foundr4  r5  r   r   text/event-stream; charset=utf-8r  no-cacheX-Accel-Bufferingr  
Connectionr  T	subscriber  s   : heartbeat

)
stream_endr   cancelunsubscribe)r   rN   r?   r  r  r/  r[   r(  r  r  r  r  r  _CLIENT_DISCONNECT_ERRORSrH  r  _SSE_HEARTBEAT_INTERVAL_SECONDSr  r  r  r  r  r  r  r,  r  )
r6  r7  rP   r6   r  journal_available
subscriberr3   r  r  s
             r   r  r    s   	&,		B{RD))!,I[##F~	&EN Y%5i%@%@ A A ATY 	& 	& 	& %	&  	IWw(:;CHHHHc"""N,NOOOOZ888/666L'222	4PQS4T4TUUUU( 	 	 	D	t'.v{'C'CO!!###J#(JKKK444+T222g...	(nn5TnUUtt;   ##$6777##%%% ,/	::H +WeT8<<<<WeT***999#	" $    V##(F(F#"":....    V##(F(F#"":....    $#
 4s   	 A* *A98A9D3 3
E ?E -J /H J AIJ IAJ K# 
J$!K# #J$$K# <K 
KK#L!9LL!
LL!LL!c                 2   t          |                     dd                                                    }|st          d          	 t	          |          }n# t
          $ r t          d          w xY wt          t          |dd          pd          }||fS )Nr5   rI   r@  r0  r<  )r   r?   r   rh   r   r   r$  r@   )body_or_queryr   r   r<  s       r   _terminal_session_and_workspacer	    s    
mb11
2
2
8
8
:
:C 0.///, , , ,*+++,)'!["*E*E*KLLI	>s   A A2c                    	 t          |          \  }}ddlm}  |||t          |                    d          pd          t          |                    d          pd          t          |                    d                              }t          | d	||j        |                                d
          S # t          $ r(}t          | t          |          d          cY d }~S d }~wt          $ r(}t          | t          |          d          cY d }~S d }~wt          $ r(}t          | t          |          d          cY d }~S d }~ww xY w)Nr   )start_terminalrowsr7  colsr.   restart)r	  r	  r	  T)r  r5   r<  r  r4  r  r  )r	  r  r	  r  r?   r  r(  r<  r  r   r&  r   rh   r[   r+  )r6  r   r   r<  r	  termr   s          r   r,  r,    s   58>>Y//////~TXXf%%+,,TXXf%%+,,),,--
 
 
 !!^==??	 
 
 	
  ) ) )7CFFC(((((((( ) ) )7CFFC(((((((( 5 5 57OA..444444445sB   B7B: :
EC'!E'E4DEE$EEEc                 0   	 t          |d           t          |                    dd                    }t          |          dk    rt	          | dd          S ddlm}  ||d         |           t          | d	d
i          S # t          $ r(}t	          | t          |          d          cY d }~S d }~wt          $ r(}t	          | t          |          d          cY d }~S d }~wt          $ r(}t	          | t          |          d          cY d }~S d }~ww xY w)Nr5   r  rI   i    zinput too large  r   )write_terminalr  Tr4  r  r  )r%  r   r?   ro   r&  r  r	  r(  r   rh   r[   r+  )r6  r   r  r	  r   s        r   r-  r-    sU   5l###488FB''((t99tw 13777//////tL)40004,''' ) ) )7CFFC(((((((( ) ) )7CFFC(((((((( 5 5 57OA..444444445sH   AB )B 
DB0*D0D=C D D-D
DDc           	      .   	 t          |d           ddlm}  ||d         t          |                    d          pd          t          |                    d          pd                     t          | d	d
i          S # t          $ r(}t          | t          |          d          cY d }~S d }~wt          $ r(}t          | t          |          d          cY d }~S d }~wt          $ r(}t          | t          |          d          cY d }~S d }~ww xY w)Nr5   r   )resize_terminalr	  r7  r	  r.   )r	  r	  r  Tr4  r  r  )r%  r  r	  r  r?   r(  r   r&  r   rh   r[   r+  )r6  r   r	  r   s       r   r.  r.    sZ   5l###000000TXXf%%+,,TXXf%%+,,	
 	
 	
 	

 4,''' ) ) )7CFFC(((((((( ) ) )7CFFC(((((((( 5 5 57OA..444444445sB   A?B 
DB/)D/D<CDD,D	DDc                     	 t          |d           ddlm}  ||d                   }t          | d|d          S # t          $ r(}t          | t          |          d          cY d }~S d }~ww xY w)Nr5   r   r|  T)r  closedr  )r%  r  r}  r(  rh   r&  r   )r6  r   r}  r	  r   s        r   r/  r/    s    )l###//////\ 23388999 ) ) )7CFFC(((((((()s   9< 
A.A)#A.)A.c                    t          |j                  }|                    ddg          d         }|st          | d          S ddlm}  ||          }|t          | ddid	          S |                     d
           |                     dd           |                     dd           |                     dd           |                     dd           | 	                                 	 	 	 |j
                            t                    \  }}n# t          j        $ r | j                            d           | j                                         |j                                        rE|j
                                        r,t)          | dd|j                                        i           Y nY w xY wt)          | ||           |dv rnn# t.          t0          t2          f$ r Y nw xY wdS )Nr5   rI   r   r@  )get_terminalr   zterminal not runningr4  r5  r   r  r  r  r  r  r  r  r  Tr  s   : terminal heartbeat

terminal_closed	exit_code)r	  terminal_error)r   rN   r?   r&  r  r	  r(  r  r  r  r  r  r  r  r  r  r  r	  is_setr  r,  procpollBrokenPipeErrorConnectionResetErrorConnectionAbortedError)r6  r7  rP   r   r	  r		  r3   r  s           r   r  r    s*   	&,		B
&&t
$
$Q
'C 371222))))))<D|7$:;CHHHH#(JKKK444+T222g...	"koo6UoVVtt;   ##$?@@@##%%%;%%'' DK,=,=,?,? "3k49>>CSCS5TUUUE %&&&===	 13IJ   4s7   -G /#D G BF61G 5F66G G+*G+c                    t          |                     d                    }|d}nxt          |d          r?t          t	          |d                    r"t          |                                          }n)t	          |dd           }|d uo|                                }|d|o||d}|s	d|d<   |d	fS |s	d
|d<   |dfS |dfS )NrP  Fr  _threadi0u  )r  fallback_poll_msr  watcher_runningagent sessions not enabledr   r4  watcher not startedr  r   )r  r?   rH  r  r@   r  )r  watcherr  watcher_alive_tr   s         r   _gateway_sse_probe_payloadr%	  9  s    8<< 34455G
 	*	%	% 9(77J3O3O*P*P 9W--//00Wi..$82;;==!'-(	 G  7| 0|C<r   c                    t                      }ddlm}  |            }t          |j                                      ddg          d                                         dv }|r%t          ||          \  }}t          | ||          S |                    d          st          | dd	id
          S t          ||          \  }}	|d         st          | ddid          S | 	                    d           | 
                    dd           | 
                    dd           | 
                    dd           | 
                    dd           |                                  |                                }
	 ddlm}  |            }t          | dd|i           	 	 |
                    t                     }nH# t"          j        $ r6 | j                            d           | j                                         Y bw xY w|n&t          | |                    dd          |           n# t,          $ r Y nw xY w|                    |
           n# |                    |
           w xY wdS )zSSE endpoint for real-time gateway session updates.
    Streams change events from the gateway watcher background thread.
    Only active when show_cli_sessions (show_agent_sessions) setting is enabled.
    r   )get_watcherproberI   >   rJ   rL   rK   r5  rP  r   r 	  r4  r	  r!	  r  r   r  r  r  r  r  r  r  r  )rt  sessions_changedr1  Tr     : keepalive

Nr  )r  api.gateway_watcherr'	  r   rN   r?   r   r%	  r(  r  r  r  r  rG  rt  r,  r  r  r  r  r  r  r  r  )r6  r7  r  r'	  r"	  r(	  r   r  _probe_body_probe_statusr\  rt  initial
event_datas                 r   r  r  U  s   
 H//////kmmGV\""&&w55a8>>@@DXXE 24XwGG'&1111 <<+,, O7$@A#NNNN "<Hg!N!NK() H7$9:3GGGG#(JKKK444+T222g...A//////""$$W(:w*?@@@		RUU+JUKK

;   ##$6777##%%% !*..1CDDjQQQ		R $    	AA4sO   7$H* F8 7H* 8AG=:H* <G==,H* )I *
H74I 6H77I I'c                    |                      d           |                     dd           |                     dd           |                     dd           |                     dd	           |                                  t                      }	 	 	 |                    t
                    }nH# t          j        $ r6 | j        	                    d           | j        
                                 Y bw xY wt          | |                    dd          |           # t          $ r Y nw xY w	 t          |           n# t          |           w xY wd
S )z>SSE endpoint for lightweight session-list invalidation events.r   r  r  r  r  r  r  r  r  Tr  r*	  r  r)	  )r  r  r  r   r?   r  r  r  r  r  r  r,  r  r   )r6  r\  r/	  s      r   r  r    sy   #(JKKK444+T222g... ""A&	RUU+JUKK

;   ##$6777##%%% *..1CDDjQQQ	R %   "1%%%%"1%%%%4sI   D B/ .D /AC41D 3C44)D 
D*'D> )D**D> >Edispositionr  c                    ddl m} t          |          j                            dd                              dd          }d                    d |D                                           d          }|s<t          |          j        }d                    d |D                       }|rd	| nd	}|                    |d
          }|  d| d| S )zGBuild a latin-1-safe Content-Disposition value with RFC 5987 filename*.r   NrI   r   c              3   `   K   | ])}d t          |          cxk    rdk     r	n n|dvr|ndV  *dS r0      >   r  \r   Nordr   chs     r   rx   z-_content_disposition_value.<locals>.<genexpr>  sk         CGG!!!!c!!!!!b&;&;     r   z .c              3   `   K   | ])}d t          |          cxk    rdk     r	n n|dvr|ndV  *dS r5	  r8	  r:	  s     r   rx   z-_content_disposition_value.<locals>.<genexpr>  sk       
 
 B%%%%#%%%%%"K*?*?BBS
 
 
 
 
 
r   downloadr  z; filename="z"; filename*=UTF-8'')	r  parser   r   r%  r  r   r  r  )r1	  r  _up	safe_nameascii_fallbackr  ascii_suffixquoted_names           r   _content_disposition_valuerD	    s$   X#++D"55==dBGGIWW       eDkk   Si'ww 
 

 
 
 
 
 7CR2L222
))IB)//K 	* 	*N 	* 	*'	* 	*r   range_header	file_sizec                    | r|                      d          r|dk     rdS |                     dd          d                                         }d|v sd|vrdS |                    dd          \  }}	 |dk    r0t          |          }|dk    rdS t	          d||z
            }|dz
  }n@t          |          }|rt          |          n|dz
  }|dk     rdS t          ||dz
            }||k    s||k    rdS ||fS # t          $ r Y dS w xY w)	zAParse a single HTTP bytes range into inclusive start/end offsets.zbytes=r   Nr  r  r#  rI   r   )r   r   r   r  r  r[  rh   )rE	  rF	  specstart_send_s
suffix_lenr  rp  s           r   _parse_range_headerrL	    sN    |66x@@ IPQMMtc1%%a(..00D
d{{cootZZQ''NGUb==UJQt9z122Ea-CCLLE %8#e***9q=Cqyytc9q=))C3;;%9,,4cz   tts%   2C: AC: C: 6C: :
DDcspr  mimer  rN	  c          	      x   	 |                                 j        }n=# t          $ r t          | dd          cY S t          $ r t          | dd          cY S w xY wt          | j                            dd          |          }| j                            d          r||                     d           | 	                    d	d
|            | 	                    dd           | 	                    dd           t          |            |                                  dS |r|ndt          d|dz
            f\  }}	|r|	|z
  dz   nd}
|                     |rdnd           | 	                    d|           | 	                    dt          |
                     | 	                    dd           |r| 	                    d	d| d|	 d|            | 	                    d|           | 	                    dt          ||j                             |rY| 	                    d|           | 	                    dd           | 	                    dd           | 	                    dd            nt          |            |                                  |
r	 |                    d!          5 }|                    |           |
}|rT|                    t'          d"|                    }|sn.| j                            |           |t-          |          z  }|Tddd           n# 1 swxY w Y   n# t          $ r Y dS w xY wdS )#zKServe a file with correct MIME/disposition and optional byte-range support.Permission deniedrM  zCould not stat filer  RangerI   Ni  zContent-Rangezbytes */Accept-Rangesr  r  r  Tr   r      r   r  zbytes r#  r   r  r  Content-Security-PolicyX-Content-Type-OptionsnosniffReferrer-Policysame-originPermissions-PolicyDcamera=(), microphone=(self), geolocation=(), clipboard-write=(self)r  i   )r=  r  r   r&  r[   rL	  r  r?   r  r  r*  r  r  r   rD	  r   r  r  r  r[  r  r  ro   )r6  r  rO	  r1	  r  rN	  rF	  
byte_ranger  rp  content_lengthr   	remainingchunks                 r   _serve_file_bytesr`	    s   8KKMM)		 6 6 67/55555 8 8 8713777778 %W_%8%8"%E%EyQQJ7## 
(:c"""O-C	-C-CDDDOW555,c222'"""t)I3q)a-3H3H/IJE3(18S5[1__qN4##555---(#n*=*=>>>111 QO-Oe-O-Oc-O-OI-O-OPPP777-/I+W]Wb/c/cddd
 # 	5s;;;4i@@@-}=== R	
 	
 	
 	

 	'""" 	T"" ,au*	 ,FF3{I#>#>??E  M''...U+I   ,, , , , , , , , , , , , , , ,  	 	 	44	4sK    AAAL) #A.LL) L!!L) $L!%L) )
L76L7rQ   c                    d}|                      dd          }t          j        d|t          j                  r't          j        dd|z   |d	t          j        
          }nVt          j        d|t          j                  r*t          j        dd|z   dz   |d	t          j        
          }nd|z   dz   |z   }|                    d          S )Nz<base target="_blank">r   r%  r  z<head(?:\s[^>]*)?>flagsz(<head\b[^>]*>)z\1r   )r   rc	  z<!doctype[^>]*>z(<!doctype[^>]*>)z\1<head>z</head>z<head>)r  r  r  
IGNORECASEr  r  )rQ   r  r.  s      r   _html_preview_with_blank_basere	    s    #D::gi:00D	y&BMBBB 2v(%$,AR][[[	%t2=	A	A	A 	2v $*-
 
 
 $*T1;;wr   c                2   	 t          |                                          }n=# t          $ r t          | dd          cY S t          $ r t          | dd          cY S w xY w|                     d           |                     dd           |                     dt          t          |                               |                     d	d
           |                     d|           |                     dt          d|j
                             |                     d|           |                     dd           |                     dd           |                     dd           |                                  | j                            |           dS )zFServe sandboxed workspace HTML preview with links targeting a new tab.rQ	  rM  zCould not read filer  r   r  r  r  rS	  noner  r  inlinerU	  rV	  rW	  rX	  rY	  rZ	  r[	  T)re	  r  r   r&  r[   r  r  r   ro   rD	  r   r  r  r  )r6  r  r  rN	  r   s        r   _serve_inline_html_previewri	  (  s   8,V->->-@-@AA 6 6 67/55555 8 8 8713777778 #(BCCC(#c$ii..999000777-/I(TZT_/`/`aaa137770)<<<)=999N   M4s   !$ AAAc           	      p   ddl ddlm}m}m} t          j                            d                    }t                              dt          |dz                                                                } |            r ||           }|r ||          sd}| 
                    d           |                     d	d
           |                     dt          t          |                               |                                  | j                            |           dS t!          |j                  }	|	                    ddg          d                                         }
|
st)          | dd          S 	 t          |
                                          n!# t,          $ r t)          | dd          cY S w xY w|                                t          d                                          |dz                                  g}	 ddlm} t           |                                                      }|                                r|                    |           n# t,          $ r Y nw xY wj                            dd                                          }|r|                    j                  D ]t}|                                }|r\	 t          |                                          }|                                r|                    |           d# t,          $ r Y pw xY wut=          fd|D                       }|st)          | dd          S                                 r                                 stC          | ddid          S j"        #                                }tI          j        |d          }h d}|h dz  }dh}|	                    ddg          d         d k    }|o|d!k    }||vr||v s|r||v s|rdnd"}|rd#nd}tK          | ||d$|%          S )&a!  Serve a local file by absolute path for inline display in the chat.

    Security:
    - Path must resolve to an allowed root (hermes home, /tmp, common dirs)
    - Auth-gated when auth is enabled
    - Only image MIME types are served inline; all others force download
    - SVG always served as attachment (XSS risk)
    - No path traversal: resolved path must stay within an allowed root
    - Additional roots can be added via MEDIA_ALLOWED_ROOTS env var
      (os.pathsep-separated list of absolute paths; ":" on POSIX, ";" on Windows)
    r   N)r  r  r  ~rX   rY   s#   {"error":"Authentication required"}r  r  r  r  r    rI   zpath parameter requiredr  zInvalid pathz/tmp)r  MEDIA_ALLOWED_ROOTSc              3      K   | ]_}|                                 j                            t                    t          |          g          t          |          k    V  `d S r;   )rz   r    
commonpathr   )r   r  r  r  s     r   rx   z _handle_media.<locals>.<genexpr>  sq        ;;==S[[#d))455TB     r   zPath not in allowed locationrM  r   r  r4  r5  application/octet-stream>   	image/bmpr  r  r  r  r  >   	audio/aac	audio/mp4	audio/ogg	audio/wav	video/mp4	video/ogg
audio/flac
audio/mpeg
audio/opus
video/webmaudio/x-wavapplication/pdfvideo/quicktimer  rh	  rJ   r  
attachmentzsandbox allow-scriptszprivate, max-age=3600rM	  )&r]   r  r  r  r  r   r    r`   r^   r   r  r  ro   r  r  r  r   rN   r?   r   r&  re   r[   api.workspacer  r   r   r  r   pathsepr   rz   r   r(  r  r   r  r`	  )r6  r7  r  r  r  _HOME_HERMES_HOMEr  r   rP   raw_pathallowed_rootsr  wsextra_rootsr  rpwithin_allowedr  rO	  _INLINE_IMAGE_TYPES_INLINE_PREVIEW_TYPES_DOWNLOAD_TYPESinline_previewhtml_inline_okr1	  rN	  r  r  s                              @@r   r  r  C  s    FFFFFFFFFF$$S))**E

=#ei6G2H2HIIJJUUWWL  	\'"" 	~~b)) 	9D!!#&&&0BCCC 0#c$ii..AAA!!!M%%%F	&,		Bvvfrd##A&,,..H <75s;;;1h'')) 1 1 17NC000001 	V		##%%M444444$$&&''//1199;; 	%  $$$   
 +//"7<<BBDDK 	%%ck22 	 	D::<<D d++--Byy{{ 1%,,R000    D      !    N
  A7:C@@@==?? >&.."2"2 >7K0==== -



C<788D
   0 3 3 3  ''OVVHrd++A.#5N#;(;NO##'''N'tG\?\?\ @] (
   &4
=
!
!CWfdKAX^abbbbs8   !F% %GGAI+ +
I87I8A
L((
L54L5r  c                    	 t          t          | j                  |          }n# t          $ r d}Y nw xY w|r*|                                r|                                r|S 	 ddlm} t           ||          |          }n# t          $ r Y dS w xY w|                                r|                                r|S dS )zIResolve /api/file/raw paths from the workspace or this session's uploads.Nr   r  )	r'  r   r<  rh   rz   r   r  r  r[   )rA   r   r  r  r  attachment_targets         r   _file_raw_targetr	    s    d7#455s;;    &--// fnn&6&6 
666666()@)@)E)EsKK   tt!! !&7&?&?&A&A !  4s   "% 44$B 
BBc                      	 t          t          j        dd                    } n# t          $ r d} Y nw xY wt	          d|           dz  dz  S )NHERMES_WEBUI_FOLDER_ZIP_MAX_MB1024r  r   )r  r]   r^   rh   r  )mbs    r   _folder_zip_max_bytesr	    s_    ;VDDEE   q"::t##s   "% 44c            	          	 t          dt          t          j        dd                              S # t          $ r Y dS w xY w)Nr   !HERMES_WEBUI_FOLDER_ZIP_MAX_FILES50000rx  )r  r  r]   r^   rh   r   r   r   _folder_zip_max_filesr	    sN    1c")$GQQRRSSS   uus   /2 
A A workspace_root	max_bytes	max_filesc                 ,   ddl }g }d}|                    | d          D ]o\  }}}	t          |          }
	 |
                                                    |          sg |dd<   Fn# t
          t          f$ r
 g |dd<   Y aw xY w|	D ]}|
|z  }|                                rA	 |                                                    |          sEn# t
          t          f$ r Y Yw xY w	 |                                j	        }n# t          $ r Y w xY wt          |          |k    r	||dfc c S ||z   |k    r	||dfc c S 	 |                    |           }n# t
          $ r Y w xY w|                    |t          |          f           ||z  }q||dfS )zWalk target dir; return (files, total_bytes, hit_limit_reason_or_None).

    files is a list of (filesystem_path, archive_name) tuples ready for
    ZipFile.write. Symlinks escaping the workspace are skipped.
    r   NF)followlinksr	  r	  )r]   walkr   re   is_relative_torh   rg   
is_symlinkr=  r  ro   rf   r   r   )r  r	  r	  r	  r  rw  r  r  r~   rv  	root_pathr   fpsizearcnames                  r   _folder_download_collectr	    s5    EK XXf%X@@    dEJJ		$$&&55nEE QQQ G$ 	 	 	DGH	  	  	 DT!B}} ::<<66~FF ! !"G,   Hwwyy(   5zzY&&k;666666T!I--k;666666..00   LL"c'll+,,,4KK+	 , +t##sG   .A''BB$'CC! C!%C??
DD>E
E! E!c                 @   ddl }ddlm}  ||j                  }|                    ddg          d         }|st          | d          S 	 t          |          }n!# t          $ r t          | dd          cY S w xY w|                    d	dg          d         }	 t          t          |j
                  |          }n!# t          $ r t          | d
d          cY S w xY w|                                st          | ddid          S |                                st          | dd          S t          |j
                                                  }	t!                      }
t#                      }t%          ||	|
|          \  }}}|dk    rt          | d|ddd          S |dk    rt          | d|
ddd          S |j        pddz   }|                     d           |                     dd           |                     dt-          d|                     |                     d d!           |                     d"d#           |                                  d}|                    | j        d$|j        d%&          5 }|D ]\\  }}	 |                    ||'           |d(z  }## t8          t:          f$ r&}t<                              d)||           Y d}~Ud}~ww xY w	 ddd           n# 1 swxY w Y   t<                               d*|tC          |          ||           dS )+a  GET /api/folder/download?session_id=...&path=...

    Streams a zip of <session.workspace>/<path>. Symlinks escaping the
    workspace are skipped. Empty folders return an empty (valid) zip.
    Respects HERMES_WEBUI_FOLDER_ZIP_MAX_MB and HERMES_WEBUI_FOLDER_ZIP_MAX_FILES.
    Pre-flights the walk so size/count failures return a clean 413 with JSON
    body BEFORE any zip bytes are sent.
    r   N)r   r5   rI   r/  r0  r4  r    zinvalid pathr  r   r  r5  z<path must be a directory; use /api/file/raw for single filesr	  ztoo many filesr	  )r   r`  	configurer	  r	  zfolder too larger	  )r   limit_bytesr	  r<  z.zipr   r  zapplication/zipr  r~	  r  r  r  r  wT)moder  
allowZip64)r	  r   z folder-download: skipping %s: %sz9folder-download: streamed %d/%d files (~%d bytes) from %s)"zipfiler  r   rN   r?   r&  r   r   r'  r   r<  rh   rz   r(  r   re   r	  r	  r	  r   r  r  rD	  r  ZipFiler  ZIP_DEFLATEDr  rg   r   r   r~  r  ro   )r6  r7  r	  r   rP   r   r   r  r  r	  r	  r	  rw  r  	limit_hitzip_namewrittenzfr	  r	  r   s                        r   r  r    s)    NNN%%%%%%	&,		B
&&t
$
$Q
'C 6745556 6 6 67/555556 &&"

q
!C1d1;//55 1 1 17NC000001==?? >7K0======?? a7Z\_```!+&&..00N%''I%''I$<	9% %!E;	 K%<
 
 	   	
 K'$9
 
 	   	 *{f4H#(9:::"<::   444 g...G	Sg>R_c	d	d Jhj  	J 	JKBJW---1_- J J JA2qIIIIIIIIJ		JJ J J J J J J J J J J J J J J KKCU[&    s`   A A98A9"B= =CC;K(J! K(!K2KK(KK((K,/K,c                    t          |j                  }|                    ddg          d         }|st          | d          S 	 t	          |          }n!# t
          $ r t          | dd          cY S w xY w|                    ddg          d         }|                    ddg          d         d	k    }t          |||          }|t          | d
did          S |j        	                                }t          j        |d          }	|                    ddg          d         d	k    }
h d}|
o|	dk    }|s|	|v r|sdnd}|rdnd }|rt          | |d|          S t          | ||	|d|          S )Nr5   rI   r   r/  r0  r4  r    r=	  rJ   r   r  r5  ro	  rh	  >   application/xhtml+xmlr  r  r  r~	  zAsandbox allow-scripts allow-popups allow-popups-to-escape-sandboxr  rM	  )r   rN   r?   r&  r   r   r	  r(  r  r   r  ri	  r`	  )r6  r7  rP   r   r   r  force_downloadr  r  rO	  r	  dangerous_typesr	  r1	  rN	  s                  r   r  r  `  s   	&,		B
&&t
$
$Q
'C 6745556 6 6 67/555556
&&"

q
!CVVJ--a0C7Nac**F~7K0====
-



C<788D
 VVHrd++A.#5NMMMO#;(;N"0rT_5L5LUc5L,,jrK R`
i
M
MeiC P)'6:3OOOOWfdKQTUUUUs   A A32A3c                 $   t          |j                  }|                    ddg          d         }|st          | d          S 	 t	          |          }n!# t
          $ r t          | dd          cY S w xY w|                    ddg          d         }|st          | d          S 	 t          | t          t          |j	                  |                    S # t          t          f$ r(}t          | t          |          d          cY d }~S d }~ww xY w)	Nr5   rI   r   r/  r0  r4  r    path is required)r   rN   r?   r&  r   r   r(  r"  r   r<  rS  rh   r+  )r6  r7  rP   r   r   r  r   s          r   r  r    s6   	&,		B
&&t
$
$Q
'C 6745556 6 6 67/555556
&&"

q
!C 07.///5+D,=,=sCCDDDz* 5 5 57OA..444444445s0   A A32A3&/C D'D
D
Dc                    t          |j                                      ddg          d         }t          5  t	          j        |          }t          |t                    r|r|d         nd }t          |          }n|r|}d}nd }d}d d d            n# 1 swxY w Y   |r t          | t          |          |d          S t          | d dd          S )Nr5   rI   r   r   re  )
r   rN   r?   rD  rC  r=   ra  ro   r(  r>   )r6  r7  r   r  rw   rc  s         r   r  r    s"   
6<
 
 
$
$\B4
8
8
;C	  S!!eT"" 	!+atAJJEE 	AEEAE               	 Hd1ggFFGGGW$;;<<<s   ABBBc                    t          |j                                      ddg          d         }|st          | d          S t	          j        d          }d}d}t          5  t                              |g           	                    |           t          j        |          }t          |t                    r)|rt          |d                   nd}t          |          }n|rt          |          }d}ddd           n# 1 swxY w Y   |                     d	           |                     d
d           |                     dd           |                     dd           |                     dd           |                                  ddlm}  || d||d           	 	 	 |                    t(                    }nH# t          j        $ r6 | j                            d           | j                                         Y bw xY w|n || d|           vn# t2          $ r Y nw xY wt5          ||           dS # t5          ||           w xY w)a  SSE endpoint for real-time approval notifications.

    Long-lived connection that pushes approval events the moment they arrive,
    replacing the 1.5s polling loop.  The frontend uses EventSource and falls
    back to HTTP polling if the connection fails.
    r5   rI   r   r/  r[  r  Nr   r   r  r  r  r  r  r  r  r  r,  r.	  re  Tr  r*	  rm  )r   rN   r?   r&  r  r  rD  rY  rm  r   rC  r=   ra  r>   ro   r  r  r  r+  r,  r  r  r  r  r  r  ra  )	r6  r7  r   r\  initial_pendinginitial_countq_listr,  r   s	            r   r  r    s    6<
 
 
$
$\B4
8
8
;C 674555 	BAOM	  !,,S"55<<Q???c""fd## 	17Ad6!9oooTOKKMM 	"6llOM               #(JKKK444+T222g..."""""" 	D)=YYZZZ*
	/%%(G%HH;   ##$6777##%%%	
 D*g...
	/ $    	"#q)))))!#q))))sb   "BDD	D%H 'G H AHH HH H? 
H*'H? )H**H? ?Ic                 V   t          |j                  }|                    ddg          d         }|                    ddg          d         }|                    ddg          d         }|r)t          ||||gdd	           t	          | d
|d          S t	          | ddid          S )zIInject a fake pending approval -- loopback-only, used by automated tests.r5   rI   r   pattern_keytest_patternr  zrm -rf /tmp/testztest pattern)r  r	  pattern_keysr   Tr  r5   r   r@  r  r5  )r   rN   r?   r>  r(  )r6  r7  rP   r   r8  cmds         r   r  r    s    	&,		B
&&t
$
$Q
'C
&& 0
1
1!
4C
&&/0
1
1!
4C
 
;"!$-	 	
 	
 	
 S99:::Ww 56sCCCCr   c                     t          |j                                      ddg          d         }t          |          }|rt	          | d|i          S t	          | dd i          S )Nr5   rI   r   rf  )r   rN   r?   get_clarify_pendingr(  )r6  r7  r   rf  s       r   r  r    sg    
6<
 
 
$
$\B4
8
8
;C!#&&G 09g.///Wy$'(((r   c                    t           t          | d          S t          |j                                      ddg          d         }|st          | d          S ddlm}m}m}m	} t          j        d	          }d}d}	|5  |                    |g                               |           |                    |          pg }
|
r*t          |
d         j                  }t!          |
          }	n(|                    |          }|rt          |          }d
}	ddd           n# 1 swxY w Y   |                     d           |                     dd           |                     dd           |                     dd           |                     dd           |                                  ddlm}  || d||	d           	 	 	 |                    t,                    }nH# t          j        $ r6 | j                            d           | j                                         Y bw xY w|n || d|           vn# t6          $ r Y nw xY wt9          ||           dS # t9          ||           w xY w)a  SSE endpoint for real-time clarify notifications.

    Long-lived connection that pushes clarify events the moment they arrive,
    replacing the 1.5s polling loop.  The frontend uses EventSource and falls
    back to HTTP polling if the connection fails.
    Nzclarify SSE not availabler5   rI   r   r/  )rD  _clarify_sse_subscribersrF  rC  r[  r  r   r   r  r  r  r  r  r  r  r  r	  r.	  re  Tr  r*	  clarify)clarify_sse_subscriber&  r   rN   r?   api.clarifyrD  r	  rF  rC  r  r  rm  r   r>   r  ro   r  r  r  r+  r,  r  r  r  r  r  r  clarify_sse_unsubscribe)r6  r7  r   _clarify_lock_clarify_subs_clarify_gateway_queues_clarify_pendingr\  r	  r	  gw_q_legacyr,  r   s                 r   r  r    s9    $77888
6<
 
 
$
$\B4
8
8
;C 674555            	BAOM	 
" 
"  b))00333&**3//52 	""47<00OIIMM&**3//G ""&w-- !
" 
" 
" 
" 
" 
" 
" 
" 
" 
" 
" 
" 
" 
" 
" #(JKKK444+T222g..."""""" 	D)=YYZZZ(		.%%(G%HH;   ##$6777##%%% D)W---		. $    	 Q'''''Q''''sb    BD!!D%(D%H< G" !H< "AH'$H< &H''H< ;I <
I	I I		I I0c                 F   t          |j                  }|                    ddg          d         }|                    ddg          d         }|                    dg           }|r(t          ||||dd           t	          | d	|d
          S t	          | ddid          S )zOInject a fake pending clarify prompt -- loopback-only, used by automated tests.r5   rI   r   questionzWhich option?r  r	  )r	  choices_offeredr5   r  Tr	  r   r@  r  r5  )r   rN   r?   submit_clarify_pendingr(  )r6  r7  rP   r   r	  r  s         r   r  r  K  s    	&,		B
&&t
$
$Q
'Cvvj?"344Q7HffY##G
 
;$#*!!	 	
 	
 	
 S99:::Ww 56sCCCCr   c           	      ,   ()*+, t          |j                  }|                    ddg          d         pd                                                                ,	 ddlm}  |            +,s++                    di                               d          pd,,st           dg d          S ddlm}  |,          ,t          ,          *t          *          }|t           |          S d
t          f* fd}	 dd	l}dd	l}|j                            |j                            |j                            |j                            t$                                        dddd          }	|j                            |	          }	|	|j        vr|j                            d|	           ddlm}
  |
,          }n5# t.          $ r(}t0                              d,|           g }Y d	}~nd	}~ww xY w|sd	}+,fd}d }d },dk    s,                    d          r/ |            D ]$}||}|                     ||                     %|s&,dk    s,                    d          r
d	}d	}|r!|                    d          } ||          }n@+                    di           }|                    d          }|                    d          }|r|r	 dd	l}dd	l}|                    d          }|                    d          r| d}n| d}|j         !                    |dd| i          }|j         "                    |d           5 } |j#        |$                                          }d	d	d	           n# 1 swxY w Y   tK          |t                    r8|                    d!g           }tK          |tL                    rd" |D             }n!tK          |tL                    rd# |D             }|r*t0                              d$tO          |          |           nt0                              d%|           n2# t.          $ r%}t0                              d&|           Y d	}~nd	}~ww xY w|stP                              ,          }|r	 dd	l}+                    d'i           }tK          |t                    r|                    ,i           ni }tK          |t                    r|                    d          nd	} | s)+                    di                               d          } | r|j         !                    | ddd|  i          }|j         "                    |d           5 } |j#        |$                                          }d	d	d	           n# 1 swxY w Y   d( |                    d!g           D             }t0                              d)tO          |          ,           n3# t.          $ r&}t0                              d*,|           Y d	}~nd	}~ww xY w|s&dd+lm)}! d, |!                    ,g           D             }|s |,g dd-          S ,d.k    r	 dd/lm*}" tK          +                    d          t                    r++                    di           pi                     d          nd	}# |"||#0          \  }$}%|$}n*# t.          $ r t0                              d1           Y nw xY wdd2lm+( (,fd3))fd4|D             }& |,|&tO          |&          d-          S # t.          $ rF}'t0                              d5,|'           t           tY          |'          g d          cY d	}'~'S d	}'~'ww xY w)6u  Return the live model list for a provider.

    Delegates to the agent's provider_model_ids() which handles:
    - OpenRouter: live fetch from /api/v1/models
    - Anthropic: live fetch from /v1/models (API key or OAuth token)
    - Copilot: live fetch from api.githubcopilot.com/models with correct headers
    - openai-codex: Codex OAuth endpoint + local ~/.codex/ cache fallback
    - Nous: live fetch from inference-api.nousresearch.com/v1/models
    - DeepSeek, kimi-coding, opencode-zen/go, custom: generic OpenAI-compat /v1/models
    - ZAI, MiniMax, Google/Gemini: fall back to static list (non-standard endpoints)
    - All others: static _PROVIDER_MODELS fallback

    The agent already maintains all provider-specific auth and endpoint logic
    in one place; the WebUI inherits it rather than duplicating it.

    Query params:
        provider  (optional) — provider ID; defaults to active profile provider
    r  rI   r   rZ  r  no_provider)r   r2  )_resolve_provider_aliasNr   c                 D    t          |            t          |           S r;   )r  r(  )r   r  r6  s    r   _finishz$_handle_live_models.<locals>._finish  s#    #Iw777Wg&&&r   ..rY   zhermes-agent)provider_model_idsz+provider_model_ids import failed for %s: %sc                     dk    s                     d          sg S 	 ddlm}                      dg           }t	          |t
                    sg S g }|D ]}t	          |t                    s | |                    dd                    }                     d          r|k    r|                    |           hdk    r|s|                    |           |S # t          $ r g cY S w xY w)Nr
  r  r   )_custom_provider_slug_from_namer]  r   rI   )	r   r`  r	  r?   r=   ra  r>   r   r[   )r	  _cp_entries_matches_cp_slugr  r  s        r   $_custom_provider_entries_for_requestzA_handle_live_models.<locals>._custom_provider_entries_for_request  s0    H,,0C0CI0N0N,IJJJJJJ"%''*<b"A"AK%k488 "!	!H* 1 1)#t44 %$ ? ?PR@S@S T T#..y99 1$00 ( 4 4 4%11%1$OOC000#O    IIIs   2C BC C.-C.c                 $   g fd} ||                      dd                     |                      d          }t          |t                    r&|D ]"}t          |t                    r ||           #nt          |t                    r|D ]}t          |t                    r ||           #t          |t                    rH ||                     d          p)|                     d          p|                     d                     S )Nc                     t          | pd                                          } | r| vr                    |            d S d S d S r#  )r   r   r   )_mid_idss    r   _appendzH_handle_live_models.<locals>._custom_provider_model_ids.<locals>._append  sX    tzr??0022D *D 0 0D)))))* * 0 0r   r  rI   r2  r|  r   )r?   r=   r>   r   ra  )r	  r	  rc  r	  _itemr	  s        @r   _custom_provider_model_idsz7_handle_live_models.<locals>._custom_provider_model_ids  s7   * * * * *
 ,,---''(++gt,, 	` ' * *%dC00 *#GDMMM*  .. `!( ` `%eS11 `#GENNNN't44 `#GEIIdOO$^uyy7I7I$^UYYW]M^M^___r   c                    |                      d          }|t          |                                          }|                    d          rW|                    d          rBt          |          dk    r/t          j        |dd         d                                          }|r|S t          |                      d          pd                                          }|r't          j        |d                                          ndS )	Nre  z${}rm   r  rY  rI   key_env)r?   r   r   r   r  ro   r]   r^   )r	  r  _key_envs       r   _custom_provider_api_keyz5_handle_live_models.<locals>._custom_provider_api_key  s    wwy))#t99??,,Dt,, As1C1C AD		TU!yadR88>>@@ $#3779--344::<<6:Bryr**00222Br   r
  r  r,  re  r   z/v1z/modelsz
/v1/modelsAuthorizationzBearer r  r  r  r  c                 d    g | ]-}|                     d           |                     d d          .S r|  rI   r   r6  s     r   r{   z'_handle_live_models.<locals>.<listcomp>	   s3    &U&U&U1t&UquuT2&U&U&Ur   c                 h    g | ]/}t          |t                    r|                    d |          n|0S r|  r  r6  s     r   r{   z'_handle_live_models.<locals>.<listcomp>   s8    "_"_"_TUZ45H5H#O155q>>>a"_"_"_r   z.Live-fetched %d models from custom provider %sz*Custom provider returned no models from %sz*Live fetch from custom provider failed: %s	providersc                 d    g | ]-}|                     d           |                     d d          .S r	  r   r6  s     r   r{   z'_handle_live_models.<locals>.<listcomp>3   s9    ]]]1QRQVQVW[Q\Q\]quuT2]]]r   z)Live-fetched %d models from %s /v1/modelszLive fetch from %s failed: %s)_PROVIDER_MODELSc                     g | ]
}|d          S r	  r   r6  s     r   r{   z'_handle_live_models.<locals>.<listcomp><   s    :::q1T7:::r   )r  r2  r   nous)_build_nous_featured_set)selected_model_idz:Failed to apply Nous featured-set cap for /api/models/live)_format_ollama_labelc                    	dv r |           S d| v r|                      d          d         n| }|                     d          }g }|D ]}|                                }|dk    r|                    d           2|dv r(|                    |                                           ^|dd	                                         r|                    |           |                    |                                           d
                    |          }dD ]*}|                    |                                |          }+|S )z/Best-effort human label from a model ID string.)ollamazollama-cloudr   rY  r#  r  GPT)
r  r  gemmallamamistralqwenr  grokkimiglmNr   r3  )r
  GLMr  AIXLMoE)r   r   r   
capitalizern  r  r%  r  )
midrf  rn   r   rw   plr  orig_fmt_ollamar  s
           r   _make_labelz(_handle_live_models.<locals>._make_labelV   sN   555"{3''',/3JJciinnR((CGMM#&&EF 
2 
2WWYY;;MM%(((( G G GMM!,,..1111rrU]]__ 2MM!$$$$MM!,,..1111HHV$$E@ : :djjllD99Lr   c                 0    g | ]}|| |          d S ))r|  r  r   )r   r
  r
  s     r   r{   z'_handle_live_models.<locals>.<listcomp>o   s0    SSSsSS;;s+;+;<<SSSr   z%_handle_live_models failed for %s: %s)-r   rN   r?   r   r   r`  r[  r(  r	  r  r  r>   r  r]   r    r  r  abspathr  normpathinserthermes_cli.modelsr	  r[   r   r   r   r}   urllib.requestr  rc  r  requestRequesturlopenr  r  r=   ra  ro   _OPENAI_COMPAT_ENDPOINTSr	  r	  r 
  r   )-r6  r7  rP   _gcr	  r  r	  _sysr  
_agent_dir_pmiids_import_errcustom_provider_entryr	  r	  r	  r	  	_base_url_api_key
_model_cfgurllibr  _ep_models_url_req_respr  _data
_fetch_err_providers_cfg_provr	  _pmr	  _default_model	_featuredr   
models_outr  r
  r
  r  r  r  s-   `                                       @@@@@r   r  r  _  s	   & 
&,		BzB4((+1r88::@@BBH@<000000cee 	Bwww++//
;;ArH 	FWDDEEE 	766666**844*844	(33Wf%%%	'T 	' 	' 	' 	' 	' 	' 	'	sx'7'78H8HIYIYZbIcIc8d8d'e'e'+T9nN NJ**:66J**	  J///DDDDDD$x..CC 	 	 	LLFR]^^^CCCCCC	  t	_$(!     ,  ,	C 	C 	C  8##x':':9'E'E#??AA @ @C,403-JJ99#>>????  ._H00H4G4G	4R4R0 	( 9 5 9 9* E EI778MNNHH!$"!5!5J *z : :I)~~i88H $_ $_#_----# (..s33<<.. =-0///KK-0*<*<*<K%~55'%46J6J6J$K  6    
 $^33D!3DD =$.DJuzz||$<$<E= = = = = = = = = = = = = = = &eT22 `$)IIfb$9$9E)%66 V&U&U&U&U&U't44 `"_"_Y^"_"_"_C b"LL)Y[^_b[c[cenoooo"LL)UW`aaa$ _ _ _%QS]^^^^^^^^_  	X*..x88C XX))))%(WW["%=%=N@J>[_@`@`hN..x<<<fhE 4>eT3J3JT599Y///PTD C"www3377	BB f%~55"OOO%46F6F6F$G  6     $^33D!3DD =$.DJuzz||$<$<E= = = = = = = = = = = = = = =]]		&"8M8M]]]%PRUVYRZRZ\deee  X X XLL!@(JWWWWWWWWX
  	;::::::::CGGHb$9$9:::C 	M7BKKLLL v[??????NXY\Y`Y`ahYiYikoNpNp!z#'''2"6"6"<"!A!A'!J!J!Jvz77~^^^	1 [ [ [YZZZZZ[ 	CBBBBB	 	 	 	 	 	2 TSSSSSS
wH
!$Z2 2 3 3 	3  < < <<hKKKCGGr::;;;;;;;;<s#  A] 1A ] 2] CG ] 
G6G1,] 1G66C*] !A:Q #N
>Q 
NQ NB8Q 
] 
Q:Q50] 5Q::#] C X >#V-!X -V11X 4V15AX ] 
X2X-(] -X22;] .] 5A-[# "] #$\
] 	\

8] 
^;^^^c                 X   ddl m} ddl}t          |j                  }|                    ddg          d         }|st          | ddid	          S  |j        d
|          r|dv rt          | ddid	          S 	 t          dt          |                    ddg          d                             }t          dt          dt          |                    ddg          d                                       }n+# t          t          f$ r t          | ddid	          cY S w xY w||z  }g }	d}
|                                rt          |                    d          d d          }t!          |          }
||||z            }|D ]}	 |                                }t%          |                    dd                    }|	                    |j        |j        |j        |d           e# t0          $ r t2                              d|           Y w xY wt          | ||	|
|d          S )zList cron run output files with metadata (no content).

    Returns lightweight file listing so the frontend can render a run history
    without fetching full output for every run.
    r   
OUTPUT_DIRNrH  rI   r   job_id requiredr  r5  ![A-Za-z0-9_-][A-Za-z0-9_.-]{0,63}r$  r	  invalid job_idoffsetr  r   r  r`  50z!offset and limit must be integersr   c                 4    |                                  j        S r;   r=  r?  r   s    r   r  z&_handle_cron_history.<locals>.<lambda>   s    qvvxx?P r   Tr  r   r%  r  )r  r	  r}  usagez"Failed to stat cron output file %s)rH  r  rc  r=
  )r  r8
  r  r   rN   r?   r(  	fullmatchr  r  r[  rh   r  rz   r   r   ro   r=  _cron_output_usage_metadatar   r   r   r  r?  rg   r   r   )r6  r7  CRON_OUTr  rP   rH  r=
  r`  out_dirr  rc  	all_filespager   rA  rB
  s                   r   r  r  x   s    100000	&,		BVVHrd##A&F D7$56sCCCC 3==vFF C&T_J_J_7$45cBBBBVQBFF8cU33A67788As3BFF7TF$;$;A$> ? ?@@AA	" V V V7$GHQTUUUUUUVGDE~~ F7<<//5P5PZ^___	I./ 	F 	FAFVVXX3KKKCC   !J ""	       F F FA1EEEEEFWQWXXYYYs&   <A>C; ;%D#"D#
A!G,,%HHc           	      6   ddl m} ddl}t          |j                  }|                    ddg          d         }|                    ddg          d         }|r|st          | ddid	
          S  |j        d|          r|dv rt          | ddid	
          S ||z  |z                                  }|	                    |                                          st          | ddid	
          S |
                                st          | ddid
          S 	 |                    dd          }t          |          }	t          |          }
t          | ||||	|
d          S # t          $ r+}t          | dt          |          id
          cY d}~S d}~ww xY w)z5Return full content of a single cron run output file.r   r7
  NrH  rI   r  r   zjob_id and filename requiredr  r5  r:
  r;
  r<
  zinvalid filenamezrun not foundr4  r   r%  r  )rH  r  r   snippetrB
  r  )r  r8
  r  r   rN   r?   r(  rC
  re   r	  rz   r   _cron_output_snippetrD
  r[   r   )r6  r7  rE
  r  rP   rH  r  fpathr   rJ
  rB
  r   s               r   r  r     s   000000	&,		BVVHrd##A&Fvvj2$''*H Q Q7$BCCPPPP
 3==vFF C&T_J_J_7$45cBBBB)2244E 0 0 2 233 E7$67DDDD<<>> B7O4SAAAA9//79/EE&w//+G44V&-'$)+ + , , 	,  9 9 97CFF+C8888888889s   A
E# #
F- FFFc                 *   ddl |                     dd          d                             dd          d         }i dt          ffd}dt          ffd}|                                D ]}|                                } j        d	|j                  }|r+|                    d                                          d
<   [ j        d|j                  }|r+|                    d                                          d<    j        d|j                  }|r& ||                    d                    }	|	|	d<    j        d|j                  }
|
r' ||
                    d                    }||d<    j        d|j                  }|r|                    d          } j        d|j                  } j        d|j                  } j        d|j                  }|r! ||                    d                    d<   |r! ||                    d                    d<   |r%dvr! ||                    d                    d<    dvr"t          fddD                       }|r|d<   S )zFExtract optional token/cost metadata from a cron output markdown file.r   NrW  r   rX  r-  c                 R     j         dd| pd          }|rt          |          nd S )Nz[^0-9]rI   )r  r  )r-  cleanedr  s     r   _intishz,_cron_output_usage_metadata.<locals>._intish   s1    #')R"55&0s7|||D0r   c                      j         d| pd                    dd                    }|r"t          |                    d                    nd S )Nz[-+]?\d+(?:\.\d+)?rI   r  r   )r  r%  r  r  )r-  r  r  s     r   	_floatishz._cron_output_usage_metadata.<locals>._floatish   sM    
05;B2G2GR2P2PQQ(-7uU[[^^$$$47r   z%\*\*(?:Model|Model Used):\*\*\s*(.+)$r  z\*\*Provider:\*\*\s*(.+)$r  z(\*\*(?:Estimated cost|Cost):\*\*\s*(.+)$estimated_cost_usdz%\*\*(?:Duration|Elapsed):\*\*\s*(.+)$duration_secondsz\*\*Tokens:\*\*\s*(.+)$z([0-9][0-9,]*)\s*(?:input|in)\bz!([0-9][0-9,]*)\s*(?:output|out)\bz'([0-9][0-9,]*)\s*(?:total\s*)?tokens?\br  r  r   c              3   `   K   | ](}t                              |          pd           V  )dS )r   N)r  r?   )r   rN  rB
  s     r   rx   z._cron_output_usage_metadata.<locals>.<genexpr>   s:      VVqC		!)**VVVVVVr   )r  r  )
r  r   r   r  r   r  Ir  r  sum)r.  rb  rP
  rR
  raw_liner   model_matchprovider_match
cost_matchr  duration_matchsecondstokens_matchr-  input_matchoutput_matchtotal_matchrc  r  rB
  s                     @@r   rD
  rD
     sA   ::mQ''*00qAA!DDE1s 1 1 1 1 1 18 8 8 8 8 8 8 OO%% !F !F~~ci H$PSPUVV 	(..q117799E'N"#?suMM 	 . 4 4Q 7 7 = = ? ?E*SYJDRURWXX
 	9Z--a0011D.2*+"#KTSVSXYY 	i 4 4Q 7 788G",3() sy!;T35II 
	F &&q))E$#*%GPSPUVVK%3:&JESVSXYYL$#*%OQVX[X]^^K F(/0A0A!0D0D(E(En% H)01C1CA1F1F)G)Go& F~U::(/0A0A!0D0D(E(En%U""VVVV4UVVVVV 	*$)E.!Lr   c                 h   |                      d          }d}t          |          D ]3\  }}|                    d          s|                    d          r|} n4|dk    r d                    ||dz   d                   nd                    |                                          }|d|         pdS )	u  Extract the response body from a cron output .md file for preview.

    Contract: cron output files use markdown front-matter followed by a
    ``## Response`` (or ``# Response``) heading that marks the start of the
    agent's reply.  This function locates that heading and returns everything
    after it (up to *limit* chars).  If no heading is found the entire text
    is returned — callers should be aware that front-matter fields (model,
    timestamp, …) may appear in the snippet.
    r   rY  rW  rX  r   r   Nz(empty))r   	enumerater   r  r   )r.  r`  r  re  r0  r   r   s          r   rK
  rK
  !  s     JJtELU##  4??=)) 	T__\-J-J 	LE	 4@13D3DDIIeL1,--.///$))TYJZJZaaccD<$9$r   c                    ddl m} t          |j                  }|                    ddg          d         }t          |                    ddg          d                   }|st          | ddid	
          S ||z  }g }|                                rt          |	                    d          d d          d |         }|D ]o}		 |	
                    dd          }
|                    |	j        t          |
          d           E# t          $ r t                              d|	           Y lw xY wt          | ||d          S )Nr   r7
  rH  rI   r`  r  r   r9
  r  r5  r   c                 4    |                                  j        S r;   r@
  rA
  s    r   r  z%_handle_cron_output.<locals>.<lambda>$!  s    16688;L r   Tr  r   r%  r  )r  r   z"Failed to read cron output file %s)rH  outputs)r  r8
  r   rN   r?   r  r(  rz   r   r   r   r   r   rh  r[   r   r   )r6  r7  rE
  rP   rH  r`  rF
  rf
  rw  r   txts              r   r  r  !  s}   000000	&,		BVVHrd##A&Fw&&q)**E D7$56sCCCCGG~~ Fw||F++1L1LVZ[[[\b]b\bc 	F 	FAFkk79kEEAF?Z[^?_?_``aaaa F F FA1EEEEEFWG<<===s   AD%D0/D0c           	      x   t          |j                  }|                    ddg          d         }|r4t          |          \  }}t	          | ||t          |d          d          S t          5  d t                                          D             }ddd           n# 1 swxY w Y   t	          | d|i          S )	z/Return running status for one or all cron jobs.rH  rI   r   r   )rH  r  elapsedc                 ^    i | ]*\  }}|t          t          j                    |z
  d           +S )r   )rM  rK  )r   jidrT  s      r   rS  z'_handle_cron_status.<locals>.<dictcomp>7!  s2    ___&#qsE$)++/155___r   Nr  )	r   rN   r?   rU  r(  rM  rJ  r   r  )r6  r7  rP   rH  r  ri
  all_runnings          r   r  r  .!  s   	&,		BVVHrd##A&F `+F33VERY[\L]L]^^___	 ` `__DVD\D\D^D^___` ` ` ` ` ` ` ` ` ` ` ` ` ` `Wy+.///s   /$BB#&B#c           
      8   ddl }t          |j                  }t          |                    ddg          d                   }	 ddlm}  |d          }g }|D ]
}|                    d          }	|	st          |	t                    rY	 |j         	                    |	
                    d	d
                                                    }
n&# t          t          f$ r Y w xY wt          |	          }
|
|k    rl|                    |                    dd          |                    dd          |                    dd          |
|                    d          dud           t          | ||d          S # t           $ r t          | g |d          cY S w xY w)z=Return cron jobs that have completed since a given timestamp.r   Nsincer  r  Tr  last_run_atr  r  r|  rI   r   Unknownlast_statusr  rl  F)rH  r   r  completed_atrl  )r  rn
  )r  r   rN   r  r?   r  r  r=   r   fromisoformatr%  r  rh   r  r   r(  ImportError)r6  r7  r  rP   rn
  r  rq  r  ri  last_runr  s              r   r  r  ;!  s   OOO	&,		B"&&3%((+,,E?''''''y$/// 	 	Cww}--H (C(( %!*88 ((h77 ikk B #I.   H 8__Ezz"""%''$"3"3 #	 : :"%''-"C"C(*/2ww7L/M/MUZ/Z    +FFGGG ? ? ?"u==>>>>>?s9   AE9 A CE9 C E9 C  BE9 9FFc                    	 ddl m}  |            }|dz  }n+# t          $ r t          j                    dz  }|dz  }Y nw xY w|dz  }|dz  }|dz  }|                                r|                    dd	
          nd}|                                r|                    dd	
          nd}|                                r|                    dd	
          nd}	t          | t          |          t          |          t          |	          t          |          t          |          t          |          |                                r|
                                j        nd |                                r|
                                j        nd |                                r|
                                j        nd t                      d
          S )Nr   rT   memoriesrY   	MEMORY.mdUSER.mdSOUL.mdr   r%  r  rI   )
memoryr  soulmemory_path	user_path	soul_pathmemory_mtime
user_mtime
soul_mtimeexternal_notes_enabled)rZ   rU   rt
  r   r_   rz   r   r(  r-  r   r=  r?  _external_notes_sources_enabled)
r6  rU   r_   mem_dirmem_file	user_file	soul_filer{
  r  r|
  s
             r   r  r  b!  s    $777777%%''# $ $ $y{{Y&#$ $H)#Iy I ??	GI>>>  		WY??? 	 		WY??? 	
 "6** && &&x==YY8@8I8ISHMMOO44t7@7G7G7I7IS)..**33t7@7G7G7I7IS)..**33t&E&G&G	
 	
  s    %A A c                    d}t          j        d          D ]}|j                            d          r	 t	          j        |j                  }|r|ot          |j                  dk    }n%|o"|j	        dk    ot          |j                  dk    }|rTt          5  t          j        |j        d            d d d            n# 1 swxY w Y   |                    d           |dz  }# t          $ r t                              d|           Y w xY wt#          j                    rt#          j        d           t'          | d|d	          S )
Nr   r   r   r  Tr  r   z"Failed to clean up session file %s)r  rO
  )r  r   r   r   r_  r`  r   ro   r  r  r  r  rP  r  r[   r   r   r  rz   r(  )r6  r   rk  rO
  rw   r   should_deletes          r   r  r  !  s   Gh'' B B6S!! 		BQV$$A U ! :c!*oo&: ! Tag&; TAJST@T  / /L.../ / / / / / / / / / / / / / /D)))1 	B 	B 	BLL=qAAAAA	B "" 3!T2222WTg66777s6   A$C'C 4C' C	C'C	C''%DDc           
      8   	 t          |d           t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY wt          |d                                                   }|st          | d          S t          |dd          }|rPt          5  |t          v r t          | dd	id
          cddd           S 	 ddd           n# 1 swxY w Y   d|_        ddlm} t          |dd          } ||j        |j        |t          |dd                    }t!          |j        pg           |_        d|dd          |_        |                                 t)          j                    j        }	|	|_        |                                 t/                      }
t          5  |
t          |	<   ddd           n# 1 swxY w Y   ddlm}  ||d         |j        |	|           t7          j        t:          |j        ||j        |j        |	dfd|dd          }|                                 t          | |	|j        |d         d          S )u   POST /api/btw — ephemeral side question using session context.

    Creates a temporary hidden session, streams the answer via SSE, then
    discards the session. The parent session is not modified.
    r5   r	  Nr0  r4  zquestion is requiredr:  r   $session already has an active streamrQ  r5  r   r  r5  rk  r<  r  r5  rk  zbtw: r(   )	track_btwT)	ephemeralr5  r  r  kwargsr  )r6   r5   r  )r%  rh   r&  r   r   r   r   r@   r  r  r(  r:  rG  r  r<  r  ra  r  r  rJ  rp  rq  rr  r  r  r
  r5   r  r  r-  r  )r6  r   r   r   r	  current_stream_id_new_sessionr5  r
  r6   r  r
  thrs                r   r&  r&  !  s   $l###j!!!! $ $ $7CFF########$6\*++ 6 6 67/5555564
#$$**,,H 472333#5t<< " 	a 	a G++7,R"S\_```	a 	a 	a 	a 	a 	a 	a 	a+	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a "666666Q 0$77N+g%9d++	  I aj.B//I-hssm--IONN
 I!*INN"$$F	 $ $#	$ $ $ $ $ $ $ $ $ $ $ $ $ $ $((((((Id< )"6	8LLL

#"Hagq{ItT!^DD	  C IIKKKWIY=Qhlmyhz{{|||sP    # 
AA	AAA. .BB"DD D3H

HHc           
      h  	
 	 t          |d           t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w	 t	          |d                   n!# t
          $ r t          | dd          cY S w xY wt          |d                                                   st          | d          S ddlm} t          d	d           |j
        j        t          d
d                    }ddd          |_        |                                 t          j                    j        |_        |                                 t%                      }t&          5  |t(          <   ddd           n# 1 swxY w Y   t          j                    j        dd         ddlm}m
 |d         |j        	 |	           	
fd}t3          j        |d          }|                                 t9          | |j        d          S )u   POST /api/background — run prompt in parallel background agent.

    Creates a hidden session, starts streaming in a daemon thread.
    Frontend polls /api/background/status for completed results.
    r5   rn  Nr0  r4  zprompt is requiredr   r
  r5  rk  r
  zbg: r(   r  )track_backgroundcomplete_backgroundc            	         	 t          	
j        
j        d           	 ddlm}  |                               }d}t          |r|j        ndpg           D ]}t          |t                    r|
                    d          dk    r1|
                    d          rGt          |
                    d	          pd                                          }|r|} n |pd
           n# t          $ r  d           Y nw xY w	 t           dz                      d           dS # t          $ r Y dS w xY w# t          $ r$ 	  d           Y dS # t          $ r Y Y dS w xY ww xY w)u?  Run the background agent, then mark the tracked task `done` with the
        last assistant reply so `/api/background/status` can surface it.  Without
        this, `complete_background()` is never called and the result is lost —
        `get_results()` would see a forever-`running` task and return nothing.
        N)r5  r   )r_  rI   r  r  r  r   z(no answer produced)z(background task failed)rC  Tr  )r-  r  r<  rG  r_  r`  reversedr  r=   r>   r?   r   r   r[   r  r  )_Sessionrj  _answer_m_contentbg_sidr
  r5  
parent_sidrn  r   r6   r  s        r   _run_bg_and_notifyz._handle_background.<locals>._run_bg_and_notify"  s!   &	 -   U::::::#==00"$KH$5$5t#RPRSS  B%b$// !266&>>[3P3P vvh'' ! "266)#4#4#:;;AACCH "* $#J9ZDZ[[[[ U U U##J9STTTTTU
&////7747HHHHH    	 	 	##J9STTTTTT   	sk    E C
C/ .E /D	E D		E !D0 0
D>:E =D>>E 
E/E
E+&E/*E++E/Tr  )r  r6   r5   )r%  rh   r&  r   r   r   r   rG  r  r@   r<  r  r  rJ  rp  rq  rr  r:  r  r  r  r  r
  r
  r5   r  r  r  r(  )r6  r   r   r
  bgr  r
  r
  r
  r
  r
  r5  r
  rn  r   r6   r  s            @@@@@@@@r   r'  r'  !  s   $l###h $ $ $7CFF########$6\*++ 6 6 67/555556h  &&((F 270111666666Q 0$77N	+g%9d++	
 
 
B $fSbSk##BHGGIII
 I#BGGIII"$$F	 $ $#	$ $ $ $ $ $ $ $ $ $ $ $ $ $ $jllrr"GDDDDDDDDl#J]FZGVDDD, , , , , , , , , , , ,\ 
"4T
B
B
BCIIKKKW'	QSQ^__```s>    + 
AAAA A6 6BB=FFFr  r  c                    |sdS t          t          | dd          pg           }|r|d         }t          |t                    r|                    d          dk    rd                    t          |                    d          pd                                                    }d                    t          |pd                                                    }||k    rdS d|d	}t          |t          t          f          r|d
k    rt          |          |d<   |rt          |          |d<   | j
                            |           dS )a2  Materialize the current user turn for eager first-turn persistence.

    The streaming thread still receives ``pending_user_message`` so existing
    cancel/recovery/final-merge paths keep their current contract. Eager mode
    only adds a durable display-message checkpoint before the agent launches.
    Nr  rY  r  r  r3  r   rI   r  r   r  attachments)ra  r@   r=   r>   r?   r  r   r   r  r  r  r   )	r   r  r
  r  r  r  latest_textmsg_textuser_msgs	            r   /_checkpoint_user_message_for_eager_session_saver
  ;"  sF     GAz4006B77H "fd## 	

6(:(:f(D(D((3vzz)'<'<'B#C#C#I#I#K#KLLKxxCI2 4 4 6 677Hh&&3//H*sEl++ 0
Q #J 4"&{"3"3Jhr   c                 L    t          | pd                                          dv S )NrI   )rI   r  zNew Chatr+  )r  s    r   "_is_default_or_empty_session_titler
  T"  s&    u{!!##'CCCr   r  rn  fallbackc                 |    t          | pd                                          }|s|S t          d|dg|          p|S )NrI   r  r  )r   r   r  )rn  r
  r.  s      r   _provisional_title_from_promptr
  X"  sL    v|""$$D 48898DDPPr   )r  r<  c                   || _         || _        || _        || _        || _        || _        ||nt          j                    | _        t          | dd          }t          |          r*t          ||pd          }	|	rt          |	          s|	| _        t                      dk    rt          | ||| j                   |                                  dS )a  Persist chat-start state according to webui.session_save_mode.

    ``deferred`` keeps the existing sidecar/WAL-backed behaviour: save pending
    fields but leave the display transcript empty until the agent merges the
    result. ``eager`` additionally writes the current user turn into messages so
    a process restart immediately after /api/chat/start preserves the prompt as
    a normal session message. Empty sessions are never saved here because this
    helper only runs after a non-empty message is validated.
    Nr  r  eager)r<  r  r5  r:  r=  r>  rK  r?  r@   r
  r
  r  r  r
  rJ  )
r   r  r
  r<  r  r5  r6   r  r  provisional_titles
             r   &_prepare_chat_start_session_for_streamr
  _"  s    ( AKAG%A"A A'A)3)?::TY[[AAw--M)-88 (:3@[Q[\\ 	(%GHY%Z%Z 	('AG"$$//7 		
 	
 	
 FFHHHHHr   c                     t          | dd          dk    oGt          | dd            o5t          | dd            o#t          | dd            ot          | dd            S )Nr  r  r  r:  r=  r   r   r_  s    r   _is_hidden_empty_sessionr
  "  s}    7J'':5 	2:t,,,	2-t444	2 14888	2 ?D111r   )r
  r5  normalized_modelrM  goal_relatedr
  r
  c                2   |pg }|r|                     d          nd t          | dd          }	|	r|r|                     d          nd t          5  |	t          v }
ddd           n# 1 swxY w Y   |
r|r|                     d          nd d|	ddS |r|                     d	          nd t	          |            |s)| j        t          v rd
}t          j        | j                   t          j	                    j
        }t          | j                  }|r|                     d          nd |5  |r|                     d          nd t          |           }t          | ||||||           ddd           n# 1 swxY w Y   |rt          d           |r|                     d          nd i }	 ddlm}  || j        d|d|||||| j        d	          }n,# t$          $ r t&                              dd
           Y nw xY w|r|                     d          nd t+          |           |r|                     d          nd t-                      }t          5  |t          |<   ddd           n# 1 swxY w Y   |r
d
t.          |<   |r|                     d          nd t1          j        t4          | j        |||||f||dd
          }|                                 || j        | j        |                    d          | j        d}|r||d<   |r||d<   |S ) zHPersist pending state, register an SSE channel, and start an agent turn.active_stream_checkNr:  active_stream_lock_waitrf  r
  rQ  )r   r:  _statusstale_stream_cleanupTsession_lock_waitsave_pending_state)r  r
  r<  r  r5  r6   rZ  turn_journal_submittedr   )append_turn_journal_eventr  r  )	r3   r6   r  r   r
  r<  r  r5  r  z-Failed to append submitted turn journal eventr   r  stream_registrationworker_thread_start)r5  r
  r
  turn_id)r6   r5   r?  r
  r  rH  effective_model_provider)r  r@   r  r  rP  r5   r  rY  rp  rq  rr  r  r
  r
  r   api.turn_journalr
  r?  r[   r   r~  r  r  r  r  r  r-  r  r?   r  )r   r  r
  r<  r  r5  r
  rM  r
  r
  current_activer6   session_lockwas_hidden_empty_sessionjournal_eventr
  r  r
  rg  s                      r   _start_chat_stream_for_sessionr
  "  s    #K *.7DJJ$%%%4#5t<< %15?

,---4 	: 	:.'9N	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	,0:DJJ'(((d?$5   /3<

)***!!$$$
  8AL,EEE!)!,777
 I*1<88L'+5DJJ"###	 
 
,0:

'(((d#;A#>#> .#)	
 	
 	
 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 
   4$]333,0:DJJ'(((dMW>>>>>>11L$&*&"02
 

 
  W W WFQUVVVVVW(,6DJJ#$$$$y!!!)-7DJJ$%%%4"$$F	 $ $#	$ $ $ $ $ $ $ $ $ $ $ $ $ $ $  .)-I&)-7DJJ$%%%4

#lC	9kJ"0,OO	  C IIKKKl2 $$Y// H  ,&+"# >/=+,OsH   
A''A+.A+-?E88E<?E<0&G &H ?H I00I47I4c                       t          d          )a  Return the runner-local client when a supervised backend exists.

    Slice 4d wires the `/api/chat/start` selection point without silently falling
    back to the legacy in-process runtime when `runner-local` is explicitly
    requested. The supervised runner backend itself is intentionally not created
    in this helper yet; a later slice can replace this factory with the concrete
    client while keeping the route contract stable.
    z+runner-local chat backend is not configured)NotImplementedErrorr   r   r   _runtime_runner_client_factoryr
   #  s     K
L
LLr   c                     t          t          | di           pi           }i }dD ]}||v r||         ||<   |                    d| j                   |                    d| j                   |S )zAExpose only the legacy browser-facing chat-start response fields.r   )
r6   r5   r?  r
  r  rH  r
  r   r:  r
  r6   r5   )r>   r@   rm  r6   r5   )r   r   rg  r8  s       r   #_chat_start_response_from_run_startr
  #  s    769b117R88GH ) ) '>>#CLHSMV%5666f&7888Or   	goal_argsc                     t          | pd                                                                          }|r|dk    rdS |dv r|S |dv rdS dS )zCReturn the bounded RuntimeAdapter goal action for WebUI /goal args.rI   r  )pauseresume)r  stopdoner  r   r   )r
  actions     r   _runtime_adapter_goal_actionr
  ##  si    b!!''))//11F Vx''x$$$***w5r   c           
         ! 	 t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY wt          |                    d          pd                                          }|rF	 ddlm	} |d	k    r&|
                    |          st          | d
d          S n# t          $ r d}Y nw xY w|rht          t          |dd          |          sIt          t          |dd          p!t          |dd          pt          |dd                    }|s||_        t          |dd          }d!|r9t           5  |t"          v !ddd           n# 1 swxY w Y   !st%          |           	 ddlm}  |t          |dd                     n# t(          $ r d Y nw xY wddlmm}	m}
 t          |                    dd          p|                    dd          pd          }|                                                                }t          |                                o|dvo!           }dx}x}x}}d}|r	 t          t5          |                    d          p|j                            }n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w|                    d          p|j        }d|v r|                    d          nt          |dd          }t;          ||          \  }}} |	|j                   }ddlm }m!} dt          dt          dt          dtD          f !fd}tG          |          } |            r= ||          }|$                    |j        ||          }tE          |j%                  }n ||j        ||          }|                    dd           s/|                    d!          d"k    rd#nd}tM          | ||$          S t          |                    d%          pd                                          }|rK|l	 t          t5          |                    d          p|j                            }n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w|Z|                    d          p|j        }d|v r|                    d          nt          |dd          }t;          ||          \  }}}tO          ||g ||||d &          }tQ          |)                    d'd(          pd(          }|*                    |           |dk    r* |
|j        |            d|d<   tM          | ||$          S tM          | |          S ))z@Handle WebUI /goal command controls and optional kickoff stream.r5   Nr0  r4  rk  rI   r   _PROFILE_ID_RErC   invalid profiler  r  context_messagesr=  r:  F)r{  )goal_command_payloadgoal_state_snapshotrestore_goal_stater  r.  )r  r
  r
  r  r
  r
  r<  r  r5  )r  r  _actionrF   c                 "     | |          S )N)stream_runningr  r   )r5   r
  r.  r
  r  r
  s      r   _legacy_goal_updatez1_handle_goal_command.<locals>._legacy_goal_updatey#  s)    ##)%	
 
 
 	
r   )goal_delegater  Tr   agent_runningrQ  r5  kickoff_prompt)r  r
  r<  r  r5  r
  r
  r
  r   )+r%  rh   r&  r   r   r   r?   r   rZ   r
  rC
  rt
  rE   r@   r  rk  r  r  rP  r{  r[   	api.goalsr
  r
  r
  r   r$  r<  r  rF  r5   r  r  r  r>   r
  update_goalr   r(  r
  r  rP  r	  )"r6  r   r   r   requested_profiler
  has_persisted_turnsr
  r{  r
  r
  r
  goal_actionwill_kickoffr<  r  r5  r
  previous_goal_staterequested_modelr;  r  r  r
  goal_adapter_actionrA  control_resultr   r  r
  stream_responser
  r  r
  s"                                  @@@r   r(  r(  /#  s   $l#### $ $ $7CFF########$6\*++ 6 6 67/555556 DHHY//5266<<>> #	#333333 I--n6N6NO`6a6a-7$5s;;; 	# 	# 	# "	# *It1L1LN_!`!` *"Az4(( 8q,d338q0$77
 

 # 	*)AI#5t<<N ) 	: 	:.'9N	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	)%a(((<<<<<<2271i3N3NOO    XWWWWWWWWWDHHVR((FDHHVR,@,@FBGGI//##))++K 	UU	 L
 =A@I@@)9 [	(5dhh{6K6K6Zq{[[\\II 	( 	( 	(wA''''''''	(((7++6qw  4'' HH%&&&,d33 	
 3Z3
 3
/~/ 21!,\ZZZXXXXXXXX
 
c 
 
 
 
 
 
 
 
 
 
 7yAA   T--<OPPP ,,L
 
 ~-..%%al4GSS;;tT"" 2G,,??S'&1111%566<"==CCEEN  6, 9$((;:O:O:^STS^ _ _``		 , , ,7CFF++++++++,="hhw//:17O $t++ )***Q 0$77 
 7^"7 73E>#3 9)-	
 	
 	
 _((C88?C@@'''S==q|-@|\\\\!GDMWgf5555Wgs    
AAAAA! !A?>A?;1C. .C=<C=
FF #F 9 G G)(G)6K 
K4K/)K4/K486R/ /
S 9SS S c                 
   	 r                     d          nd  	 t          |d           nK# t          $ r>}t          | t	          |                    cY d }~r                                 S S d }~ww xY wr                     d          nd  	 t          |d                   n8# t          $ r+ t          | dd          cY r                                 S S w xY wr                     d          nd  t	          |                    d          pd          	                                }|r]	 d	d
l
m} |dk    r=|                    |          s(t          | dd          r                                 S S n# t          $ r d}Y nw xY w|rht          t          dd           |          sIt!          t          dd           p!t          dd           pt          dd                     }|s|_        r                     d          nd  t	          |                    dd                    	                                }|s't          | d          r                                 S S r                     d          nd  t%          |                    d          pg           d d         }r                     d          nd  	 t'          |                    d                    nK# t          $ r>}t          | t	          |                    cY d }~r                                 S S d }~ww xY w|                    d          pj        }	d|v r|                    d          nt          dd           }
r                     d          nd  t+          |	|
          \  d	dlmm}m}m}m}  |            s
 |            rd|dt8          ffdfd }	  ||t:          !          }|t=          d"          |                     |j         ||t          dd           d#d$d%i&	  	                  }nO# t<          $ rB}tC          | d't	          |          id()          cY d }~r                                 S S d }~ww xY wtE          |          }ntG          ||*          }tI          |%                    d+d,          pd,          }r                     d-          nd  tC          | ||)          r                                 S S # r                                 w w xY w).Nvalidate_session_idr5   r   r0  r4  validate_profilerk  rI   r   r
  rC   r
  r  r  r
  r=  normalize_messager   zmessage is requirednormalize_attachmentsr
  r   resolve_workspacer<  r  r5  r  )r  StartRunRequestbuild_runtime_adapterr  runtime_adapter_runner_enabledr
  rF   c           
      p    t          | j        | j        | j        p| j        p| j        p          S )Nr  r
  r<  r  r5  r
  rM  )r
  r   r
  r<  r  r  )r
  rM  r  r5  r
  r   r<  s    r   _legacy_start_runz-_handle_chat_start.<locals>._legacy_start_run#  sN    5 ' 3%/<9!-05#*#3#E~%5	 	 	 	r   c                                  S )N)start_run_delegater   )r  r
  s   r   _legacy_adapter_factoryz3_handle_chat_start.<locals>._legacy_adapter_factory$  s    22FWXXXXr   )legacy_adapter_factoryrunner_client_factoryz-runtime adapter selection returned no adapterr  router  )	r5   r   r
  r<  rk  r  r  r4   r  r   i  r5  r
  r
  r   rf  )&r  r%  rh   r&  r   r  r   r   r?   r   rZ   r
  rC
  rt
  rE   r@   r  rk  _normalize_chat_attachments%_resolve_chat_workspace_with_recoveryr  rF  r  r  r
  r
  r  r
  r>   r
  r
  	start_runr5   r(  r
  r
  r  rP  )r6  r   rM  r   r
  r
  r
  r  r
  r
  r;  r
  r
  r  r
  r
  rA  r   r  rg  r  r  r
  r  r5  r
  r   r<  s     `                  @@@@@@@r   r)  r)  #  s   v-1;

()))t	(D,'''' 	( 	( 	(wA'''''''`  	KKMMMM	c	(%)3

=!!!t	:D.//AA 	: 	: 	:w 3S9999V  	KKMMMM	Y	:*.8

%&&&D 3 3 9r::@@BB 	''777777$	11.:R:RSd:e:e1w(93??F  	KKMMMM	E  ' ' '$&!!!' 	._WQ	45P5PRc%d%d 	."&:t,, <10$77<14d;;# #
 ' .
 .	+/9

&'''T$((9b))**0022 	7w 566b  	KKMMMM	a 04=

*+++1$((=2I2I2ORPPQTRTQTU+/9

&'''T	(=a+AVAVWWII 	( 	( 	(wA'''''''T  	KKMMMM	W	(((7++6qw  4'' HH%&&&,d33 	
 15>

+,,,$2Y3
 3
/~/	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 #"$$ 1	(F(F(H(H 1	
? 
t 
 
 
 
 
 
 
 
 
 
 
Y Y Y Y Y YC//+B*H   ?-.]^^^ **#O#$< #$/"+ '9d ; ;!/#&")+<!=
 
 
  ' C C C7CHH"5cBBBBBBBB"  	KKMMMM	%C:6BBHH5'#-!1	 	 	H X\\)S118S99(,6

#$$$$(6222 	KKMMMM	4 	KKMMMM	s   T3 5 T3 
A=A8A=T3 8A==T3 B0 /T3 0C%T3 $C%%AT3 :1F T3 FT3 FCT3 7AT3 #K: 9T3 :
ML= M!T3 =MB2T3 5A Q T3 
R"  R R"T3 R""A9T3 3Uc                 B   |dv}|r|nt          | dd          }	 t          t          |                    S # t          $ r |r Y nw xY wt          t          t	                                          }|| _        	 |                                  n# t          $ r Y nw xY w|S )zIRecover stale implicit session workspaces without hiding explicit errors.r#  r<  N)r@   r   r$  rh   r  r<  rJ  r[   )r   requested_workspaceexplicitrc   r
  s        r   r  r  4$  s    "*4H'/R##WQT5R5RI,Y77888    		 	 ,-?-A-ABBCCHAK	   Os!   7 AA:B 
BBc                 R   g }t          | t                    s|S | D ]}t          |t                    r4t          |                    d          p|                    d          pd                                          }t          |                    d          pd                                          }t          |                    d          pd                                          }|p|||d}|                    d          }t          |t                    r||d<   |                    d          }t          |t                    r||d<   |                    |           Mt          |                                          }	|	r|                    |	ddd           |S )	a  Normalize attachment payloads from the browser.

    Older clients send a list of filenames. Newer clients send upload result
    objects containing name/path/mime/size so image attachments can be supplied
    to Hermes as native multimodal inputs for the current turn.
    r   r  rI   r    rO	  )r   r    rO	  r	  is_image)	r=   ra  r>   r   r?   r   r  r  r   )
raw_attachmentsr  r  r   r    rO	  attr	  r	  r-  s
             r   r  r  F$  s    Jot,,  K KdD!! 	Ktxx''E488J+?+?E2FFLLNNDtxx''-2..4466Dtxx''-2..4466D<4tDDC88F##D$$$ #"Fxx
++H(D)) +"*Jc""""IIOO%%E K!!5"b"I"IJJJr   c                    t          |d                   }t          |                    dd                                                    }|st	          | ddid          S 	 t          t          |                    d          p|j                            }n4# t          $ r'}t          | t          |                    cY d	}~S d	}~ww xY wt          |j
                  5  ||_        t          |                    d
          p|j        d|v r|                    d          nt          |dd	                    d	d         \  }}||_        ||_        d	d	d	           n# 1 swxY w Y   ddlm} |5  t"          j                            d          }	t          |          t"          j        d<   t"          j                            d          }
t"          j                            d          }dt"          j        d<   |j
        t"          j        d<   d	d	d	           n# 1 swxY w Y   	 ddlm} t*          5  ddlm}m}  |t3          |j        t          |dd	                              \  }}}d	}	 ddlm} ddlm}  |||          }|                    d          }|s|                    d          }|s|                    d          }n+# t<          $ r}t?          d| d           Y d	}~nd	}~ww xY wtA          |t                    r/|!                    d          r ||          \  }}|s|r|}|s|r|} |||||ddtE                      |j
                   }dd!lm#}m$}m%}m&}m'}m(}m)}   | t          |j                            }!d"|j         d#}"tU          |j+        pg           }#tU           |||                    }$|,                    |!|z   |" ||$t[                      $          |j
        |%          }%d	d	d	           n# 1 swxY w Y   |5  |	!t"          j        .                    dd	           n|	t"          j        d<   |
!t"          j        .                    dd	           n|
t"          j        d<   |!t"          j        .                    dd	           n|t"          j        d<   d	d	d	           n# 1 swxY w Y   n# |5  |	!t"          j        .                    dd	           n|	t"          j        d<   |
!t"          j        .                    dd	           n|
t"          j        d<   |!t"          j        .                    dd	           n|t"          j        d<   d	d	d	           w # 1 swxY w Y   w xY wt          |j
                  5  |%                    d&          p|$}& ||$|&          }' ||$|'          }'|'|_/         ||#|$ ||#|&          |          |_+        |j0        d'k    rtc          |j+        |j0                  |_0        |2                                 d	d	d	           n# 1 swxY w Y   	 tg                                          d(          r\dd)l4m5}(  |(|j
        |j6        pd|j7        pd|j8        |j        |j0        ts          |j+                  t          |d*d	          +           n*# t<          $ r tt          ;                    d,           Y nw xY wt	          | |%                    d-          pd|%                    d.d          rd/nd0|<                                d&|j+        iz  d1 |%=                                D             d2          S )3zJFallback synchronous chat endpoint (POST /api/chat). Not used by frontend.r5   r   rI   r   zempty messager  r5  r<  Nr  r5  r  r   )	_ENV_LOCKTERMINAL_CWDHERMES_EXEC_ASKHERMES_SESSION_KEYrJ   r  )r  r  r  r  r  re  r  r,  z2[webui] WARNING: resolve_runtime_provider failed: T)r  r  r  r  )!_dedupe_replayed_context_messages*_merge_display_messages_after_agent_result#_restore_display_reasoning_metadata_restore_reasoning_metadata_sanitize_messages_for_api_context_messages_for_new_turn_workspace_context_prefixz#Active workspace at session start: aj  
Every user message is prefixed with [Workspace::v1: /absolute/path] indicating the workspace the user has selected in the web UI at the time they sent that message. This tag is the single authoritative source of the active workspace and updates with every message. It overrides any prior workspace mentioned in this system prompt, memory, or conversation history. Always use the value from the most recent [Workspace::v1: ...] tag as your default working directory for ALL file operations: write_file, read_file, search_files, terminal workdir, and patch. Never fall back to a hardcoded path when this tag is present.)r  )r  r  r  r  persist_user_messager  r  sync_to_insights)sync_session_usagerk  )r5   r  r  r  r  r  r  rk  z&Failed to update session cost trackingr  	completedr
  partialc                 &    i | ]\  }}|d k    ||S )r  r   )r   rN  r  s      r   rS  z%_handle_chat_sync.<locals>.<dictcomp>%  s#    JJJ1!z//q!///r   )answerr  rA   r   )>r   r   r?   r   r(  r$  r<  rh   r&  r  r5   rF  r  r@   r5  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  ra  r  r  r[  rP  r
  r  r  rJ  r  api.state_syncr  r  r  r  ro   r   r   r  r  ))r6  r   r   r  r<  r   r  r5  r  old_cwdold_exec_askold_session_keyr  r  r  rV  rI  r&
  r'
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  workspace_ctxworkspace_system_msg_previous_messages_previous_context_messagesr   _result_messages_next_context_messagesr  s)                                            r   r*  r*  d$  sf
   D&''A
dhhy"%%
&
&
,
,
.
.C B7O4SAAAA$1$((;2G2G2V1;WWXX		 $ $ $7CFF########$	 	.	. * * GHHW(*:d*B*BDHH%&&&PQSceiHjHj!
 !
 1"!~ )* * * * * * * * * * * * * * * ('''''	 8 8*..00%(^^
>"z~~&788*..)=>>(+
$%+,<
'(8 8 8 8 8 8 8 8 8 8 8 8 8 8 8`C%%%%%% O	 O	       
 ,B+A+AGWQ@PRV5W5WXX, ,(FIy HVVVVVVPPPPPPFF,'   779--  4 #
 3 3I  4 #
 3 3I   MMM        
 )S)) )i.B.B9.M.M )$F$Fy$Q$Q! 'G '&H  )X ) (IG""  !!6!8!8<  E                  65c!+6F6FGGMPak P P P ! "&aj&6B!7!7)-.L.LQPS.T.T)U)U&++*S03%?%?@Z`j`l`l%m%m%m%( ,  FSO	 O	 O	 O	 O	 O	 O	 O	 O	 O	 O	 O	 O	 O	 O	b  	C 	C
~t4444-4
>*#
0$77770<
,-&
3T::::3B
/0	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	CY 	C 	C
~t4444-4
>*#
0$77770<
,-&
3T::::3B
/0	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 
!	.	.  !::j11O5O!<!<&"
 "
 "C!B&""
 "
 4??&//0BDTUU	
 

 7j   QW55AG	)              ,???122 	999999<^0qo2 /gg!!*oo  9d33     ? ? ?=>>>>>?jj!1228b &

; = =Lff9yy{{j!*%==JJJJJ		
 	
  s   "6B 
C
#C?C
C
!A3E  E$'E$3BHH #H (S 5<P2AKP
K7K2-P2K77DPS PS PS BS  SSU>BU2&U>2U66U>9U6:U>BX33X7:X7?A=Z= =$[$#[$c           
         	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 ddlm}m} t          |                    d                    }|                    d          du} ||d         |d         |                    d          pd |                    d	          pd
|                    d          pg |                    d          pd           }i }|||d<   |sd|d<   |r ||d         |          p|}t          | dt          |          d          S # t          $ r+}t          | dt          |          id          cY d }~S d }~ww xY w)Nrn  scheduler   )
create_job
update_jobrk  rl  Fr   deliverlocalrV   r  )rn  r*  r   r-  rV   r  r|  Tr  ri  r   r  r5  )r%  rh   r&  r   r  r+  r,  ry  r?   r(  rn  r[   )	r6  r   r   r+  r,  rk  rl  ri  post_create_updatess	            r   r0  r0  %  s   $h
++++ $ $ $7CFF########$944444444/0C0CDD"hh'<==UJj>*%&!!)THHY''2788H%%+((7##+t
 
 
 !-4	*" 	?9> 56 	D*SY(;<<CC.?.D.DEEFFF 9 9 97CFF+C8888888889s8    
AA A A	C7E 
E6 E1+E61E6c                     	 ddl m} n# t          $ r t                      }Y nw xY wddddddg}t	          |          D ],}|                    ||                                d           -t          | d|i          S )	z2Return available delivery platforms for cron jobs.r   )_KNOWN_DELIVERY_PLATFORMSr.  zLocal (save output only))r-  r  r5  zOrigin (reply to creator)r  )r  r2  r[   	frozensetr   r   r
  r(  )r6  r2  r  r   s       r   r  r  4%  s    0<<<<<<< 0 0 0$-KK!!!0 $>??%@AAI 011 F F4$//2C2CDDEEEEW{I.///s   	 $$c                    	 t          |d           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wddlm} 	 i }|                                D ],\  }}|dk    r|dk    rt          |          ||<   %||||<   -n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w ||d         |          }|st          | dd          S t          | dt          |          d          S )	NrH  r   )r,  rk  Job not foundr4  Tr/  )
r%  rh   r&  r   r  r,  r  ry  r(  rn  )r6  r   r   r,  r  rN  r  ri  s           r   r1  r1  C%  sg   $h $ $ $7CFF########$$$$$$$
$JJLL 	 	DAqH}}I~~:1==


	  $ $ $7CFF########$
*T(^W
-
-C 27OS111WT*;C*@*@AABBBs6    
A?AAAB 
CB>8C>Cc                    	 t          |d           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wddlm}  ||d                   }|st          | dd          S t          | d|d         d          S )NrH  r   )
remove_jobr5  r4  T)r  rH  )r%  rh   r&  r   r  r7  r(  )r6  r   r   r7  r  s        r   r2  r2  [%  s    $h $ $ $7CFF########$$$$$$$	DN	#	#B 27OS111WTT(^<<===    
A?AAc           
         |                     dd          }|st          | d          S ddlm}  ||          }|st          | dd          S t	          |          \  }}|r#t          | d|d	t          |d
          d          S t          |           ddlm	}  |            }t          |          }	t          j        t          |||	fd                                           t          | d|dd          S )NrH  rI   r9
  r   )get_jobr5  r4  Falready_runningr   )r  rH  r  ri
  rT   T)r  r  r  r  )r  rH  r  )r?   r&  r  r:  rU  r(  rM  rM  rZ   rU   r  r  r  r  r  )
r6  r   rH  r:  ri  r;  ri
  rU   _profile_home_execution_profile_homes
             r   r3  r3  h%  s9   XXh##F /7-...!!!!!!
'&//C 27OS111/77OW ;&DU',Wa'8'8: : ; ; 	;v 433333**,,M8==-S-I`4ajnooouuwwwWTVyIIJJJr   c                     |                     dd          }|st          | d          S ddlm}  |||                     d                    }|rt	          | d|d	          S t          | d
d          S )NrH  rI   r9
  r   )	pause_jobr9   r9   Tr/  r5  r4  )r?   r&  r  r?  r(  )r6  r   rH  r?  r   s        r   r4  r4  %  s    XXh##F /7-...######Yvdhhx&8&8999F 7f55666w---r   c                     |                     dd          }|st          | d          S ddlm}  ||          }|rt	          | d|d          S t          | dd	          S )
NrH  rI   r9
  r   )
resume_jobTr/  r5  r4  )r?   r&  r  rB  r(  )r6  r   rH  rB  r   s        r   r5  r5  %  s    XXh##F /7-...$$$$$$ZF 7f55666w---r   c                     |st          | d           d S 	 t          |          S # t          $ r t          | dd           Y d S w xY w)Nr@  r0  r4  )r&  r   r   )r6  r5   s     r   _git_sessionrD  %  sh     G*+++t:&&&   G(#...tts   % AAc                 R    t          | |          }|d S t          |j                  S r;   rD  r   r<  r6  r5   rA   s      r   _git_session_workspacerH  %  s,    7J//Gt!"""r   c                 V    t          | |          }|dS |t          |j                  fS )Nr   rF  rG  s      r   _git_session_and_workspacerJ  %  s1    7J//GzD*++++r   c                     t          | dd           }|sdS 	 ddlm}m} |5  ||v cd d d            S # 1 swxY w Y   d S # t          $ r Y dS w xY w)Nr:  Fr   )r  r  )r@   r`  r  r  r[   )rA   r6   r  r  s       r   _git_locked_by_active_streamrL  %  s    !3T::I u44444444 	( 	('	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(   uus'   
? 2? 6? 6? 
AAc                     ddl m}m}m}  |            s"t	          |  |d| dd          d           dS t          |          rt	          |  |d	d
          d           dS dS )Nr   )rr  WORKSPACE_GIT_DESTRUCTIVE_ENV!workspace_git_destructive_enabledz7Destructive workspace Git operations are disabled. Set z=1 to enable them.destructive_git_disabledrM  r5  TzQA session run is active. Wait for it to finish before running this Git operation.active_streamrQ  F)r  rr  rN  rO  r  rL  )r6  rA   rr  rN  rO  s        r   !_git_reject_destructive_if_unsaferR  %  s              -,.. 	{Jg{{{*  	
 	
 	
 	
 t#G,, 	c  	
 	
 	
 	
 t5r   c                    t          |j                  }t          | |                    ddg          d                   }|dS 	 ddlm}m} t          | d ||          i          S # |$ r}t          | |          cY d }~S d }~ww xY w)Nr5   rI   r   Trq  r~  )	r   rN   rH  r?   r  rr  rs  r(  r  )r6  r7  rP   r<  rr  rs  r   s          r   r  r  %  s    	&,		B&w|bT0J0J10MNNIt$CCCCCCCC5**Y"7"78999 $ $ $########$   "A( (B-B<BBc                    t          |j                  }t          | |                    ddg          d                   }|dS 	 ddlm}m} t          | d ||          i          S # |$ r}t          | |          cY d }~S d }~ww xY w)Nr5   rI   r   T)rr  git_branchesbranches)	r   rN   rH  r?   r  rr  rV  r(  r  )r6  r7  rP   r<  rr  rV  r   s          r   r  r  %  s    	&,		B&w|bT0J0J10MNNIt$EEEEEEEE:||I'>'>?@@@ $ $ $########$rT  c           	         t          |j                  }t          | |                    ddg          d                   }|dS |                    ddg          d         }|                    ddg          d         }|st	          | d          S 	 dd	lm}m} t          | d
 ||||          i          S # |$ r}t          | |          cY d }~S d }~ww xY w)Nr5   rI   r   Tr    r  rx  zpath required)rr  git_diffdiff)
r   rN   rH  r?   r&  r  rr  rY  r(  r  )	r6  r7  rP   r<  r    r  rr  rY  r   s	            r   r  r  &  s
   	&,		B&w|bT0J0J10MNNIt66&2$"D66&:,''*D -7O,,,$AAAAAAAA688ItT#B#BCDDD $ $ $########$s   $B6 6C;C
CCr  c           	      h    t          | t          |          t          |dd          pdd|          S )Ncode
git_failed)r   r\  r5  )r(  r+  r@   )r6  errr  s      r   r  r  &  sJ    $S))C66F,	
 	
    r   c                    |                      d          }|+|                      d          r|                      d          g}t          |t                    r|g}t          |t                    st	          d          d |D             S )Npathsr    zpaths must be a listc                 ,    g | ]}t          |          S r   r  )r   r    s     r   r{   z(_git_paths_from_body.<locals>.<listcomp>%&  s    ,,,$CII,,,r   )r?   r=   r   ra  rh   )r   	raw_pathss     r   _git_paths_from_bodyrc  &  s    !!ITXXf--XXf%%&	)S!!  K	i&& 1/000,,),,,,r   c                    	 t          |d           t          |          }t          | |d                   \  }}|dS t          | |          rdS ddlm}m} t          | d |||          d          S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   Tr   )rr  	git_stager  r~  )r%  rc  rJ  rR  r  rr  re  r(  rh   r&  r   r  )r6  r   r`  rA   r<  rr  re  r   s           r   r6  r6  (&  s   $l###$T**7lASTT4,Wg>> 	4BBBBBBBBii	5.I.IJJKKK $ $ $7CFF######## $ $ $########$:   :A5 A5 $A5 5
C?B!C!C)B>8C>Cc                    	 t          |d           t          |          }t          | |d                   \  }}|dS t          | |          rdS ddlm}m} t          | d |||          d          S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   Tr   )rr  git_unstagerf  )r%  rc  rJ  rR  r  rr  ri  r(  rh   r&  r   r  )r6  r   r`  rA   r<  rr  ri  r   s           r   r7  r7  :&  s   $l###$T**7lASTT4,Wg>> 	4DDDDDDDDkk)U.K.KLLMMM $ $ $7CFF######## $ $ $########$rg  c                    	 t          |d           t          |          }t          | |d                   \  }}|dS t          | |          rdS ddlm}m} t          | d |||t          |	                    d                              d          S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   Tr   )rr  git_discarddelete_untracked)rl  rf  )r%  rc  rJ  rR  r  rr  rk  r(  r  r?   rh   r&  r   r  )r6  r   r`  rA   r<  rr  rk  r   s           r   r8  r8  L&  sF   $l###$T**7lASTT4,Wg>> 	4DDDDDDDD"{%)$((3E*F*F%G%G   

 

 
	
  $ $ $7CFF######## $ $ $########$s;   :B B AB 
C%!C=C%C%C C% C%rm  r  c                 b   ddl m} |                                pd}|                    |dt                    5  ddlm}m}m}m	} t          t          |dd          pd                                          }	t          t          |d	d          pd                                          pd }
|	r ||	|
          n	 |            } ||          \  }}}d }	 dd
lm} ddlm}  |||          }|                    d          }|s|                    d          }|s|                    d          }n2# t$          $ r%}t                              d|           Y d }~nd }~ww xY wt)          |t                    r/|                    d          r ||          \  }}|s|r|}|s|r|}d| dd|dg}||||d}	 ddlm}  |d|          \  }}|g|re|j        j                            ||          }t          |j        d         j        j        pd                                          cd d d            S n2# t$          $ r%}t                              d|           Y d }~nd }~ww xY wddlm}  |||||ddg dtA          j!                    j"        d d                     }|#                    || g dtA          j!                    j"        d d          !          }t          |                    d"          pd                                          cd d d            S # 1 swxY w Y   d S )#Nr   r  rC   zgit commit messager  )r  r  r  r  r  rI   r5  r  r  r  re  r  r,  z9git commit message runtime provider resolution failed: %sr  r  r  r  r  r  r  r  r  zIgit commit message auxiliary model failed; falling back to main model: %sr  r  Tzgit-commit-message-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   r  r  rp  rq  rr  r  )rm  r  rA   r  r`  r  r  r  r  session_modelsession_providermodel_for_resolutionr  r  r  r  r  r  r  r  r  r  r  r  r  r  r   rg  r  r  r   s                                  r   _llm_git_commit_messagerq  h&  s    ,,,,,,!99;;HyN		7	7 
8 
 
 W? W?
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 GGWb99?R@@FFHHww0@"EEKLLRRTT\X\ /''7GHHH,,.. 	
 7M6LMa6b6b3^^	ZRRRRRRLLLLLLBB((  C  GGI..M! 5!$!4!4! 5!$!4!4 	Z 	Z 	ZLLTVXYYYYYYYY	Znc** 	*~/H/H/S/S 	* B B> R RGX  (W ( '! *h *!) -8844

 ' &$	
 
	jHHHHHH$=$=)% % %!J	 %)%%?6==#% >   8+A.6>D"EEKKMMCW? W? W? W? W? W? W? W?D  	j 	j 	jLLdfhiiiiiiii	j 	&%%%%%##!CTZ\\-=bqb-ACC	
 	
 	
 ''$(!#@$*,,*:2A2*>@@	 ( 
 
 6::.//5266<<>>oW? W? W? W? W? W? W? W? W? W? W? W? W? W? W? W? W? W?sj   BL$AD43L$4
E#>EL$E##AL$<A2H<;L$<
I+I&!L$&I++B,L$$L(+L(c           
         ddl m}m}m} 	 t	          |d           t          |d                   }t          |j                  } ||          } |t          |d         |d         |                    }|s |d          t          | d|t          |                    d	                    d
          S # t          $ r t          | dd          cY S t          $ r'}	t          | t          |	                    cY d }	~	S d }	~	w|$ r}	t!          | |	          cY d }	~	S d }	~	wt"          $ rB}	t$                              d           t          | t)          |	          d          cY d }	~	S d }	~	ww xY w)Nr   )rr  clean_generated_commit_messagestaged_commit_message_promptr5   rm  r  r  No commit message was generatedTr  r  r   r  r0  r4  z$git commit message generation failedr  )r  rr  rs  rt  r%  r   r   r<  rq  r(  r  r?   r   r&  rh   r   r  r[   r   r  r+  )
r6  r   rr  rs  rt  rA   r<  rn  r   r   s
             r   r9  r9  &  s            5l###d<011*++	--i8800#F?$;VM=R\cddd
 
  	G##$EFFF'VZZXcMdMdHeHeffggg 6 6 67/55555 $ $ $7CFF######## $ $ $######## 5 5 5?@@@7OA..444444445sH   B+B8 8E,	E,D :E, E,DE,E,*7E'!E,'E,c           
         ddl m}m}m} 	 t	          |d           t          |          }t          |d                   }t          |j                  } |||          } |t          |d         |d         |                    }	|	s |d          t          | d|	t          |                    d	                    d
          S # t          $ r t          | dd          cY S t          $ r'}
t          | t!          |
                    cY d }
~
S d }
~
w|$ r}
t#          | |
          cY d }
~
S d }
~
wt$          $ rB}
t&                              d           t          | t+          |
          d          cY d }
~
S d }
~
ww xY w)Nr   )rr  rs  selected_commit_message_promptr5   rm  r  r  ru  Tr  rv  r0  r4  z-selected git commit message generation failedr  )r  rr  rs  rx  r%  rc  r   r   r<  rq  r(  r  r?   r   r&  rh   r   r  r[   r   r  r+  )r6  r   rr  rs  rx  r`  rA   r<  rn  r   r   s              r   r:  r:  &  s            5l###$T**d<011*++	//	5AA00#F?$;VM=R\cddd
 
  	G##$EFFF'VZZXcMdMdHeHeffggg 6 6 67/55555 $ $ $7CFF######## $ $ $######## 5 5 5HIII7OA..444444445sH   B;C E<%	E<.D
E<E<D-'E<-E<:7E71E<7E<c           
         	 t          |dd           t          | |d                   \  }}|dS t          | |          rdS ddlm}m} t          |  |||                    dd                              S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   r   Tr   )rr  
git_commitrI   )r%  rJ  rR  r  rr  rz  r(  r?   rh   r&  r   r  )r6  r   rA   r<  rr  rz  r   s          r   r;  r;  '  s   $lI...7lASTT4,Wg>> 	4CCCCCCCC**YB0G0GHHIII $ $ $7CFF######## $ $ $########$s:   ,A8 A8 5A8 8
CB$C$C,C;CCc           
         	 t          |dd           t          |          }t          | |d                   \  }}|dS t          | |          rdS ddlm}m} t          |  |||                    dd          |                    S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   r   Tr   )rr  git_commit_selectedrI   )r%  rc  rJ  rR  r  rr  r|  r(  r?   rh   r&  r   r  )r6  r   r`  rA   r<  rr  r|  r   s           r   r<  r<  '  s!   $lI...$T**7lASTT4,Wg>> 	4LLLLLLLL--i)R9P9PRWXXYYY $ $ $7CFF######## $ $ $########$s:   ;B B 6B 
CB4.C4C<CCCr
  c                    	 t          |d           t          | |d                   \  }}|dS |dv rt          | |          rdS ddlm}m}m}m} |||d}	t          |  |	|         |                    S # t          $ r'}
t          | t          |
                    cY d }
~
S d }
~
w|$ r}
t          | |
          cY d }
~
S d }
~
ww xY w)Nr5   T>   r  r  r   )rr  	git_fetchgit_pullgit_push)r  r  r  )r%  rJ  rR  r  rr  r~  r  r  r(  rh   r&  r   r  )r6  r   r
  rA   r<  rr  r~  r  r  actionsr   s              r   r=  r=  &'  s1   $l###7lASTT4%%%*KGU\*]*]%4VVVVVVVVVVVV 
 

 /'&/)44555 $ $ $7CFF######## $ $ $########$s:   +A6 A6 0A6 6
C B"C"C*B?9C?Cc                 L   	 t          |ddd           t          | |d                   \  }}|dS t          | |          rdS ddlm}m}  ||t          |                    dd                    t          |                    dd                    |                    d	          t          |                    d
                    t          |                    dd                              }t          | d|                    d          |                    d          |                    d          |                    dd          d          S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   refr	  Tr   )rr  git_checkoutrI   r.  
new_branchtrack
dirty_modeblock)r  r  r  r  rW  current_branchr   )r  r~  rW  r  r   )r%  rJ  rR  r  rr  r  r   r?   r  r(  rh   r&  r  )r6  r   rA   r<  rr  r  r   r   s           r   r>  r>  <'  s   $lE62227lASTT4,Wg>> 	4EEEEEEEE##$$))**xx--txx(())488L'::;;
 
 
 zz(++"JJz22"(**-=">">!::i44 	
 	
 		
  $ $ $7CFF######## $ $ $########$s;   -E E DE 
F#F;F#F#	FF#F#c                 0   	 t          |ddd           t          | |d                   \  }}|dS t          | |          rdS ddlm}m}  ||t          |                    dd                    t          |                    dd                    |                    d	          t          |                    d
                              }t          | d|                    d          |                    d          |                    d          |                    dd          |                    dd          t          |                    d                    |                    d          t          |                    d                    |                    dd          |                    d          d          S # t          $ r'}t          | t          |                    cY d }~S d }~w|$ r}t          | |          cY d }~S d }~ww xY w)Nr5   r  r	  Tr   )rr  git_stash_and_checkoutrI   r.  r  r  )r  r  r  rW  r  r   
stash_namestashedrestored_stashrestore_failedrestore_errorrestore_stash)r  r~  rW  r  r   r  r  r  r  r  r  )r%  rJ  rR  r  rr  r  r   r?   r  r(  rh   r&  r  )r6  r   rA   r<  rr  r  r   r   s           r   r?  r?  ^'  s.   #$lE62227lASTT4,Wg>> 	4OOOOOOOO''##$$))**xx--txx(())
 
 
 zz(++"JJz22"(**-=">">!::i44$jjr::

9 5 566"(**-=">">"&vzz2B'C'C"D"D!'OR!@!@!'O!<!< 
 
 	
   $ $ $7CFF######## $ $ $########$s;   -G G FG 
HG3-H3H;H
HHc                    	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                st          | dd          S |
                                r:|                    d          st          | d          S t          j        |           n|                                 t          | d|d         d	          S # t          t           f$ r'}t          | t#          |                    cY d }~S d }~ww xY w)
Nr5   r    r0  r4  r  	recursivez(Set recursive=true to delete directoriesTr  r    )r%  rh   r&  r   r   r   r'  r   r<  rz   r   r?   r  r   r  r(  r   r+  r6  r   r   r   r  s        r   r@  r@  '  s   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/5555560d1;//f>>}} 	7w 0#666==?? 	88K(( P7$NOOOM&!!!!MMOOOtF|<<===( 0 0 07OA..////////0sW    
AA A A	A A=<A=AE	 8E	 AE	 	FE<6F<Fc                    	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                st          | dd          S |
                                rt          | d          S |                    |                    dd          d	
           t          | d|d         |                                j        d          S # t          t           f$ r'}t          | t#          |                    cY d }~S d }~ww xY w)Nr5   r    r0  r4  r  z Cannot save: path is a directoryr   rI   r   r   T)r  r    r	  )r%  rh   r&  r   r   r   r'  r   r<  rz   r   
write_textr?   r(  r=  r  r   r+  r  s        r   rA  rA  '  s   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/5555560d1;//f>>}} 	7w 0#666==?? 	Dw BCCC$((9b11GDDDD$v,@UVV
 
 	
 ( 0 0 07OA..////////0sW    
AA A A	A A=<A=AE #E 2AE FF;FFc                 (   	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                rt          | d          S |j
                            dd           |                    |                    dd	          d
           t          | dt          |                    t          |j                                      d          S # t          t           f$ r'}t          | t#          |                    cY d }~S d }~ww xY w)Nr5   r    r0  r4  zFile already existsTr   r   rI   r   r   r  )r%  rh   r&  r   r   r   r'  r   r<  rz   r   r   r  r?   r(  rf   r   r+  r  s        r   rB  rB  '  s   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/555556
0d1;//f>>==?? 	7w 5666D4888$((9b11GDDDD#f.@.@akARAR.S.S*T*TUU
 
 	
 ( 0 0 07OA..////////0sQ    
AA A A	A A=<A=AE BE F*FFFc                    	 t          |ddd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                st          | dd          S |d         
                                }|rd|v sd|v rt          | d	          S |j        |z  }|	                                rt          | d
| d          S |                    |           t          |                    t          |j                                      }t          | d|d         |d          S # t          t          t           f$ r'}t          | t#          |                    cY d }~S d }~ww xY w)Nr5   r    new_namer0  r4  r  r   r	  zInvalid file namezA file named "z" already existsT)r  old_pathnew_path)r%  rh   r&  r   r   r   r'  r   r<  rz   r   r   renamerf   r(  r   rg   r+  )r6  r   r   r   r4   r  destnew_rels           r   rC  rC  '  s   $lFJ7777 $ $ $7CFF########$6\*++ 6 6 67/5555560d1;//f>>}} 	7w 0#666
#))++ 	53(??dh.>.>w 3444}x';;== 	Mw K K K KLLLdd&&tAK'8'899::4<WUUVVV1 0 0 07OA..////////0s]    
AAAA
A   A>=A>AF 3F 1F 5A"F G/GGGc                    	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                rt          | d          S |
                    d           t          | dt          |                    t          |j                                      d          S # t          t          t          f$ r'}t          | t          |                    cY d }~S d }~ww xY w)	Nr5   r    r0  r4  zPath already existsT)r   r  )r%  rh   r&  r   r   r   r'  r   r<  rz   r   r(  rf   r   rg   r+  r  s        r   rD  rD  '  s   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/555556	0d1;//f>>==?? 	7w 5666T"""D#f.@.@akARAR.S.S*T*TUU
 
 	
 1 0 0 07OA..////////0sQ    
AA A A	A A=<A=AD( AD( (E&?E!E&!E&c                 |   	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                st          | d| d          S t          j                    }|dk    r%t          j        ddt          |          g           nU|d	k    r't          j        d
dt          |          z   g           n(t          j        dt          |j                  g           t          | d|d         d          S # t          t           t"          f$ r'}t          | t%          |                    cY d }~S d }~ww xY w)Nr5   r    r0  r4  File not found: Darwinr  z-RWindowszexplorer.exez/select,zxdg-openTr  )r%  rh   r&  r   r   r   r'  r   r<  rz   r6  r  
subprocessPopenr   r(  r   rg   r+  )r6  r   r   r   r  r  s         r   rE  rE  '  s   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/5555560d1;//f>>}} 	B w ;6 ; ;SAAA""XfdCKK89999y  nj3v;;.FGHHHH j#fm*<*<=>>>tF|<<===1 0 0 07OA..////////0sQ    
AA A A	A A=<A=AE= B+E= =F;F60F;6F;c                    	 t          |dd           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }t          | dt          |          d          S # t          t          t          f$ r'}t          | t          |                    cY d}~S d}~ww xY w)u"  Resolve a relative workspace-rooted path into an absolute on-disk path.

    The right-click "Copy file path" action (#1764) wants to put the
    absolute path on the user's clipboard so they can paste it into a
    terminal, editor, or anywhere else without having to round-trip through
    the OS file browser. The frontend can't compute the absolute path on
    its own — `safe_resolve` joins against the session's workspace root
    which only the server knows. The handler here is a thin lookup; no
    filesystem mutation, no OS-specific dispatch. We do NOT require the
    target to exist (unlike `_handle_file_reveal`) — copying the path of a
    just-deleted file is still useful, and refusing would force callers
    to special-case 404s for an action that cannot fail destructively.
    r5   r    Nr0  r4  Tr  )r%  rh   r&  r   r   r   r'  r   r<  r(  r   rg   r+  r  s        r   rF  rF  (  s:   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/5555560d1;//f>>s6{{;;<<<1 0 0 07OA..////////0sJ    
AA A A	A A=<A=AC	 	D D<DDc                 D   	 t          |dd           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w	 t	          |d                   }n!# t
          $ r t          | dd          cY S w xY w	 t          t          |j                  |d                   }|	                                st          | d| d          S t          |          }ddl
m}  |                                d	i           }t          |t                    si }|                    d
d          }|                    dd          }	|r1|	r/|                    |          r|	|t!          |          d         z   }|                    dd          }
t#          j        |
          }|t&          j                            dd          }t&          j                            dd          }t&          j                            dd          }ddddt&          j                            |dddd          t&          j                            |ddd          t&          j                            |ddd          g}|D ])}|r%t          |          	                                r|} n*|t          | d|
d          S t/          j        ||g           t3          | d|d         d          S # t          t4          t6          f$ r'}t          | t9          |                    cY d}~S d}~ww xY w) a  Open a workspace file or folder in VS Code (#2735).

    Reads optional ``vscode`` config block from config.yaml:

        vscode:
          command: code          # executable on PATH; defaults to "code"
          host_path_prefix: /home/user/projects       # Docker host path
          container_path_prefix: /app/workspace       # matching container path

    If ``host_path_prefix`` and ``container_path_prefix`` are both set,
    paths that begin with ``container_path_prefix`` are translated to the
    host prefix before being handed to VS Code.  This lets users running
    Hermes WebUI inside Docker still open files in their local editor.
    r5   r    Nr0  r4  r  r   rZ  vscodecontainer_path_prefixrI   host_path_prefixr  r\  LOCALAPPDATAPROGRAMFILESzC:\Program FileszPROGRAMFILES(X86)zC:\Program Files (x86)z/usr/local/bin/codezD/Applications/Visual Studio Code.app/Contents/Resources/app/bin/codez/usr/bin/codez/snap/bin/codeProgramszMicrosoft VS Codebinzcode.cmdzVS Code command not found: zn. Install VS Code and ensure the 'code' CLI is on PATH, or set vscode.command in config.yaml to the full path.Tr  )r%  rh   r&  r   r   r   r'  r   r<  rz   r`  r[  r?   r=   r>   r   ro   r  whichr]   r  r    r  r  r  r(  r   rg   r+  )r6  r   r   r   r  
target_strr  
vscode_cfgcontainer_prefixhost_prefixr	  resolved_cmd_local_app_data_prog_files_prog_files_x86_vscode_fallbacksfbs                    r   rG  rG  8(  sy   $lF++++ $ $ $7CFF########$6\*++ 6 6 67/555556:0d1;//f>>}} 	Bw ;6 ; ;SAAA[[
 	655555XZZ^^Hb11
*d++ 	J%>>*A2FF nn%7<< 	J 	J
0E0EFV0W0W 	J$z#6F2G2G2H2H'IIJnnY// |C((
 !jnn^R@@O*..9LMMK jnn-@B[\\O &V _j:MuV`aa[*=ujQQ_.A5*UU! (   $r((//++ #%LEIc I I I   	,
3444tF|<<===1 0 0 07OA..////////0sW    
AA A A	A A=<A=AK! G K! 2.K! !L8LLLc                    t          |                    dd                                                    }|                    dd                                          }|                    dd          }|st          | d          S t	          |                                                                          }t          |          rt          | d|           S |rW	 |                    dd	           n># t          t          f$ r*}t          | d
t          |                     cY d }~S d }~ww xY w	 t          |          n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wt                      }t!          fd|D                       rt          | d          S |                    t                    |pj        d           t'          |           t)          | d|d          S )Nr    rI   r   r  Fr	  z#Path points to a system directory: Tr   zCould not create directory: c              3   J   K   | ]}|d          t                    k    V  dS )r    Nr  )r   r	  rw   s     r   rx   z(_handle_workspace_add.<locals>.<genexpr>(  s2      
,
,11V9A
,
,
,
,
,
,r   zWorkspace already in list)r    r   r  rl  )r'  r?   r   r&  r   r`   re   r&  r   rg   r   r+  r%  rh   r   r  r   r   r   r  r(  )	r6  r   path_strr   auto_createrc   r   wssrw   s	           @r   rH  rH  (  s+    )&")=)=)C)C)E)EFFH88FB%%''D((8U++K 07./// X))++3355Iy)) O7M)MMNNN U	UOOD4O8888) 	U 	U 	Uw Sq?Q?Q S STTTTTTTT	U$%h// $ $ $7CFF########$


C

,
,
,
,
,
,
,,, 977888JJA77888CWT55666s<   C7 7D2D-'D2-D26E 
E7E2,E72E7c                     |                     dd                                          st          | d          S t                      }fd|D             }t	          |           t          | d|d          S )Nr    rI   r	  c                 ,    g | ]}|d          k    |S r  r   )r   r	  r  s     r   r{   z,_handle_workspace_remove.<locals>.<listcomp>(  s'    
3
3
3QvY(221222r   Tr  r?   r   r&  r  r  r(  )r6  r   r  r  s      @r   rI  rI  (  s    xx##))++H 07.///


C
3
3
3
3c
3
3
3CCWT55666r   c                 |   |                     dd                                          }|                     dd                                          }|r|st          | d          S t                      }|D ]}|d         |k    r||d<    nt          | dd          S t	          |           t          | d|d          S )	Nr    rI   r   zpath and name are requiredzWorkspace not foundr4  Tr  r  )r6  r   r  r   r  r	  s         r   rJ  rJ  (  s    xx##))++H88FB%%''D :4 :78999


C 8 8V9  AfIE ! 713777CWT55666r   c                    |                     dg           }|rt          |t                    st          | d          S t	                      }d |D             }g }t                      }|D ]N}|                                }||v r4||vr0|                    ||                    |                    |           O|D ]!}|d         |vr|                    |           "t          |           t          | d|d          S )a  Reorder workspaces by providing an ordered list of paths.

    Accepts {"paths": ["path1", "path2", ...]}. The workspaces list is
    rewritten so that entries appear in the given order. Any workspace
    not included in the request is appended at the end (preserves data).
    r`  z$paths is required and must be a listc                      i | ]}|d          |S r  r   )r   r	  s     r   rS  z-_handle_workspace_reorder.<locals>.<dictcomp>(  s    )))qy!)))r   r    Tr  )r?   r=   ra  r&  r  r   r   r   r   r  r(  )	r6  r   r`  r  by_path	reorderedseenrw   r	  s	            r   rK  rK  (  s    HHWb!!E D
5$// D7BCCC


C))S)))GI55D  GGII<<ATMMWQZ(((HHQKKK    V9D  QIWT;;<<<r   ro  choicec           	         d}d}g }t           5  t          j        |           }t          |t                    rw|rEt          |          D ]2\  }}|                    d          |k    r |j        |          }d} n3d}n|r |j        d          nd}|du}|st          j        | d           n1|r/|r |j        d          |k    rt          j        | d          }|du}|srt          j        |           }	|	r\t          |	          dk    rI|	d         }
t          |
dd          pi }|                    d          p|                    dd	          g}d}t          t          j        |           t                    rHt          |          r;t          | t          |          d         t          t          |                               nt          | dd           ddd           n# 1 swxY w Y   |r,|                    d          p|                    dd	          gng }d
 |D             d |D             z   }|dv r|D ]}t          | |           n>|dk    r8|D ]!}t          | |           t          |           "t          t                     d}|s|st          | |d          pd}t!          |          pt!          |          pt!          |           S )zResolve an approval through the existing callback path.

    Slice 3b keeps the RuntimeAdapter as a protocol translator: it delegates to
    this legacy helper rather than owning approval queues or callback state.
    NFro  Tr   r  r	  r	  rI   c                     g | ]}||S r   r   r   rN  s     r   r{   z,_resolve_approval_legacy.<locals>.<listcomp>2)  s    222a2222r   c                     g | ]}||S r   r   r  s     r   r{   z,_resolve_approval_legacy.<locals>.<listcomp>2)  s    5S5S5SAQR5Sa5S5S5Sr   )r  rA   alwaysr  )rD  rC  r?   r=   ra  rc
  rP  rF  ro   r@   rj  r?  r@  rA  rE  rG  r  )r   ro  r  rf  found_targetgateway_keysr  r0  r1  gw_queuegw_entrygw_datakeys_from_pendingall_keysrN  gateway_resolveds                   r   _resolve_approval_legacyr  (  s    GLL	 :6 :6S!!eT"" 	3 3 )% 0 0 	# 	#HAuyy//;>>"+%)A,,'+ ? #G*/9)%)A,,,T&d2 (S$''' 	3 3)%)M":":k"I"I",sD11&d2  	$&*3//H $CMMA--#A; "(FD99?R&{{>::^w{{=Z\?]?]>^  $ hl3''.. 	68C= 	6'Xc]1-=s8C=?Q?QRRRR'T1555u:6 :6 :6 :6 :6 :6 :6 :6 :6 :6 :6 :6 :6 :6 :6z \cjN33WMSU8V8V7Whj22,2225S5S5S5S5SSH$$$ 	$ 	$AC####	$	8		 	! 	!AC###a     !4555  Y; Y3CUSSSXWX ==KD!122K${:K:K6KKs   GG  G$'G$c                    |                     dd          }|st          | d          S |                     dd          }|dvrt          | d|           S |                     dd          }d	d
lm}m}  |            r. |t
                    }|                    |||          j        }nt          |||          }t          | ||d          S )Nr5   rI   r/  r  deny)r  rA   r  r  zInvalid choice: ro  r   r  )approval_delegate)r  r  )	r?   r&  r  r  r  r  respond_approvalr  r(  )	r6  r   r   r  ro  r  r  rA  r  s	            r   rL  rL  F)  s    
((<
$
$C 674555XXh''F:::77v77888((="--KXXXXXXXX   @--@XYYY%%c;??H%c;??WR622333r   
clarify_idrg  c                 n    |rddl m}  || ||          S t          | |d          }t          |          S )zEResolve clarify through the existing callback path without new state.r   )rv  Fr  )r	  rv  ru  r  )r   r  rg  rv  resolveds        r   _resolve_clarify_legacyr  Y)  sV      @555555$$S*h??? sH%@@@H>>r   c                 f   |                     dd          }|st          | d          S |                     d          }||                     d          }||                     d          }t          |pd                                          }|st          | d          S |                     dd          }d	d
lm}m}  |            r. |t                    }|                    |||          j	        }nt          |||          }|st          | ddddd          S t          | d|d          S )Nr5   rI   r/  rg  r  r  zresponse is requiredr  r   r  )clarify_delegateFzPClarification prompt expired or not found. The agent may have already proceeded.T)r  r   r  rQ  r5  )r  rg  )r?   r&  r   r   r  r  r  r  respond_clarifyr  r(  )	r6  r   r   rg  r  r  r  rA  r  s	            r   rM  rM  g)  sv   
((<
$
$C 674555xx
##H88H%%88H%%8>r""((**H 472333,++JXXXXXXXX   @--?VWWW$$S*h??H$S*h??  g
 
 	   	 WTx88999r   c                   ,    e Zd Zd Zd Zd Zd Zd ZdS )_ManualCompressionMemoryHandlerc                 R    t          j                    | _        d | _        i | _        d S r;   )ioBytesIOr  r  sent_headersselfs    r   __init__z(_ManualCompressionMemoryHandler.__init__)  s$    Z\\
r   c                     || _         d S r;   r5  )r  r  s     r   r  z-_ManualCompressionMemoryHandler.send_response)  s    r   c                     || j         |<   d S r;   )r  )r  r8  r-  s      r   r  z+_ManualCompressionMemoryHandler.send_header)  s    !&#r   c                     d S r;   r   r  s    r   r  z+_ManualCompressionMemoryHandler.end_headers)  s    r   c                     | j                                                             d          }|rt          j        |          ni S )Nr   )r  getvaluer  r  r  )r  rQ   s     r   r   z'_ManualCompressionMemoryHandler.payload)  s:    j!!##**733"%-tz#2-r   N)r  
__module____qualname__r  r  r  r  r   r   r   r   r  r  )  s_          
  ' ' '  . . . . .r   r  c                    | t          j                     n| } t          t                                                    D ]\  }}|                    d          dk    rt          |                    d          p|                    d          p|           }| |z
  t          k    rt                              |d            d S )Nr  r  r  r  )rK  ra  r   r  r?   r  #_MANUAL_COMPRESSION_JOB_TTL_SECONDSrP  )r  r   ri  r  s       r   "_manual_compression_cleanup_lockedr  )  s    $)+++#C17799:: 4 4S778	))377<00PCGGL4I4IPSQQ
AAA$((d3334 4r   c                    |                      d          pd}|dv||                      d          |                      d          |                      d          |                      d          d}|d	k    rJ|                      d
          }t          |t                    r|                    |           d	|d<   d|d<   n|dk    rGd|d<   |                      d          pd|d<   t	          |                      d          pd          |d<   nL|dk    rFd|d<   |                      d          pd|d<   t	          |                      d          pd          |d<   |S )Nr  r  >   r   r  r5   focus_topicr  r  )r  r  r5   r  r  r  r
  r   Tr  r   FCompression failederror_statusr  r  zCompression cancelledrQ  )r?   r=   r>   r	  r  )ri  r  r   r   s       r   "_manual_compression_status_payloadr  )  sq   WWX+)F22ggl++ww}--ggl++ggl++ G ""fd## 	#NN6""""	7		777++C/C"%cggn&=&=&D"E"E	;		777++F/F"%cggn&=&=&D"E"ENr   c           	         t                      }	 	 t          |           }n# t          $ r d }Y nw xY w|Lddlm} |                    |dt                    5  t          ||           d d d            n# 1 swxY w Y   nt          ||           t          |j	        pd          }|
                                }t          5  t                              |           }|s	 d d d            d S t          j                    }|dk    s*t          |t                     r|                    d          r?|                    dt%          |pi                     d          pd          ||d	           n|                    d
||d           d d d            d S # 1 swxY w Y   d S # t&          $ r}	t                              d| |	           t          5  t                              |           }|r;|                    ddt+          |	           dt          j                    d	           d d d            n# 1 swxY w Y   Y d }	~	d S Y d }	~	d S d }	~	ww xY w)Nr   r  zmanual compressionr  r  r  r   r  )r  r   r  r  r
  )r  r   r  z3Manual compression worker failed for session %s: %sCompression failed: )r  r   r   r  r  r  r   r"  r  r  r   _MANUAL_COMPRESSION_JOBS_LOCKr   r?   rK  r=   r>   r	  r   r[   r~  r+  )
r   r   memory_handlerrA   r  r  r   ri  r  r  s
             r   _run_manual_compression_jobr   )  s   466N0	!#&&GG 	 	 	GGG	444444??I]ou?vv ? ?(>>>? ? ? ? ? ? ? ? ? ? ? ? ? ? ? %^T:::^*1c22 ((*** 	 	*..s33C 	 	 	 	 	 	 	 	 )++C}}Jw$=$=}WAUAU}

")!$gm%8%8%A%A%YEY!Z!Z(.&)	     

"(")&)   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	,    LcSVWWW* 
	 
	*..s33C 

")!N8L8L!N!N(+&*ikk	   
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	s   ! F" 0F" 0(F" A5)F" 5A99F" <A9=AF" F F" -BFF" FF" FF" "
I,#I
AH3'I
3H7	7I
:H7	;I

Ic           
      L   	 t          |d           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wt          |                    d          pd                                          }|st          | d          S 	 t          |          }n!# t          $ r t          | dd          cY S w xY wt          |dd           rt          | dd          S t          |                    d	          p|                    d
          pd                                          d d         pd }d|i}|r||d	<   t          j	                    }t          5  t          |           t                              |          }|r_t          |          }	|	                    d          dk    rt          | |	          cd d d            S t                              |d            ||d||d}
|
t          |<   d d d            n# 1 swxY w Y   t!          j        t$          ||fd|d d          d          }|                                 t          5  t          | t          t                              ||
                              cd d d            S # 1 swxY w Y   d S )Nr5   rI   r/  r0  r4  r:  @Session is still streaming; wait for the current turn to finish.rQ  r  topicr  r  r  )r5   r  r  r  r  zmanual-compress-r  T)r  r  r   r  )r%  rh   r&  r   r?   r   r   r   r@   rK  r  r  r   r  r(  rP  r  r  r   r  )r6  r   r   r   r   r  job_bodyr  r  existing_payloadri  workers               r   r!  r!  )  s   $l#### $ $ $7CFF########$ dhh|$$*
+
+
1
1
3
3C 6745556 6 6 67/555556q$d++ e7^`cddddhh}--H'1B1BHbIIOOQQRVSVRVW_[_Kc"H ."-
)++C	& , ,*3///+//44 	4A(KK##H--::"233, , , , , , , , %((d333&
 
 ), %-, , , , , , , , , , , , , , ,0 *8_)BQB))	  F LLNNN	& f f<=U=Y=YZ]_b=c=cddeef f f f f f f f f f f f f f f f f fsT    
A?AAB   B>=B>A#H-HH
H
6JJ Jc                    t          |pd                                          }|st          | d          S t          5  t	                       t
                              |          }|s t          | dd|d          cd d d            S t          |          }t          | |          cd d d            S # 1 swxY w Y   d S )NrI   r/  Tidle)r  r  r5   )	r   r   r&  r  r  r   r?   r(  r  )r6  r   ri  r   s       r   r  r  2*  s%   
ciR..


 
 C 674555	& # #*,,,&**3// 	QWTV3OOPP	# # # # # # # #
 5S99 '""# # # # # # # # # # # # # # # # # #s   >B3B33B7:B7c                   $% d }d }d }	 t          |d           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wt          |                    d          pd                                          }|st          | d          S t          |                    d          p|                    d          pd                                          d d	         pd }	 t          |          }n!# t          $ r t          | d
d          cY S w xY wt          |dd           rt          | dd          S 	 ddl	m
}	  |	|j                  }
t          |
          dk     rt          | d          S d $d7$fd	%$fd}	 d7%fd	}dd lm} ddlm} dd lm} dd l}|                    |                    |j        t          |dd                               \  }}}d }	  ||j        |          }|                    d          }|s|                    d          }|s|                    d          }n2# t0          $ r%}t2                              d|           Y d }~nd }~ww xY wt7          |t                    r9|                    d          r$|                    |          \  }}|s|r|}|s|r|}|st          | d          S t=          |
          }t          |dd           t          |d d           t?          j         t          |d!d                     t          |d"d           f} ||          }|!                    ||||d#d$tE                      |%          }|j#        $                    |||&          } ||          } ||||||'          }|%                    |          5  t          |dd           t          |d d           t?          j         t          |d!d                     t          |d"d           f} | |k    rt          | d(d          cd d d            S  |	|j                  |k    rt          | d)d          cd d d            S ||_        ||_&        g |_'        d |_(        d |_)        g |_*        d |_+        tY          |d*+          }!|!r t[          dt          |!          d,z
            nd |_.        |!r ||!d-                   nd |_/        d }"t7          |t`                    r?|                    d.          p)|                    d/          p|                    d0          }" ||"p ||          pd          |_1        |2                                 d d d            n# 1 swxY w Y   tg          |4                                |j        |j'        |j(        |j)        |j*        |j+        t          |d1d           t          |d2d           d3z            }#tk          | d$|#||d4          S # t0          $ rE}t2                              d5|           t          | d6tm          |                     cY d }~S d }~ww xY w)8Nc                    t          | t                    sd S t          |                     d          pd          }|r|dk    rd S |                     dd          }t          |t                    r d                    d |D                       }nt          |pd          }d                    |                                                                          d d         }|                     d	          p|                     d
          }|                     d          }t          |t                    rt          |          nd}|s|s|sd S ||||dS )Nr  rI   r  r   r   c              3      K   | ]k}t          |t                    rT|                    d           dk    0t          |                    d          p|                    d          pd          V  ldS )r  r.  r   rI   Nr  rv   s     r   rx   zH_handle_session_compress.<locals>._anchor_message_key.<locals>.<genexpr>N*  s        a&& ,-55==F+B+B AEE&MM;QUU9%5%5;<<+B+B+B+B r   r3  r2   _tsr  r
  r   )r  r  r.  r
  )	r=   r>   r   r?   ra  r  r   r   ro   )r  r  r   r.  rH  r  r
  attach_counts           r   _anchor_message_keyz5_handle_session_compress.<locals>._anchor_message_keyF*  s`   !T"" 	4155==&B'' 	tv~~4%%	2&&gt$$ 	&99       DD w}"%%Dxx

%%++--dsd3UU5\\/QUU;//eeM**+5k4+H+HOs;'''a 	L 	 	4B\RRRr   c                 P   d }t          | pg           D ]}t          |t                    st          |                    d          pd                                          }|dk    rVt          |                    d          t                    st          |                    d          pd                                          }|st          j        dd|                                          }d|                                v sd|                                v r|c S d S )	Nr  rI   r  r   r  r3  zcontext compactionzcontext compression)	r
  r=   r>   r   r?   r   r   r  r  )r  r.  r  r  r   rH  s         r   "_compression_summary_from_messageszD_handle_session_compress.<locals>._compression_summary_from_messages]*  s   (.b)) 	 	Aa&& quuV}}*++1133D{""aeeI..44 !%%	**0b117799G 6&#w//5577D$

44(DJJLL88 9 tr   c                     t          | t                    sd S |                                 }|sd S t          j        dd|          }t          |          dk    r|d d          d}|S )Nr  r3  i@  i:  r  )r=   r   r   r  r  ro   )raw_textrg
  s     r   _compact_summary_textz7_handle_session_compress.<locals>._compact_summary_textr*  sr    (C(( 	4nn 	4fVS#&&s88c>>#Y###C
r   r5   rI   r/  r  r  r  r0  r4  r:  r  rQ  r   )r     z?Not enough conversation to compress (need at least 4 messages).c                 `   d}| pg D ]}t          |t                    s|                    dd          }t          |t                    r d                    d |D                       }nt          |pd          }|t          |                                          z  }t          d|          S )a0  Fallback heuristic token estimate when runtime metadata helpers are absent.

            Uses whitespace token-like word counting only. This intentionally
            over/under-estimates BPE token counts (roughly around x3/x4 scale),
            and is only for resilient fallback behavior.
            r   r   rI   r   c              3      K   | ]R}t          |t                    t          |                    d           p|                    d          pd          V  SdS r.  r   rI   Nr=   r>   r   r?   rv   s     r   rx   z]_handle_session_compress.<locals>._fallback_estimate_messages_tokens_rough.<locals>.<genexpr>*  sn       - -%a..-AEE&MMCQUU9-=-=CDD- - - - - -r   r   )	r=   r>   r?   ra  r  r   ro   r   r  )r2  rc  r  r   content_texts        r   (_fallback_estimate_messages_tokens_roughzJ_handle_session_compress.<locals>._fallback_estimate_messages_tokens_rough*  s     EZR 3 3!!T** %%	2..gt,, 6#'99 - -!(- - - $ $LL $'w}"#5#5L\//11222q%== r   c                    ||n
 |          }dt          |            dt          |           d}|d| d| d|rd| ndd	}d
| d|d          d|                    d          r|d         dz   ndz   dz   |d<   |S )zOLightweight fallback summary to keep /session/compress usable in tests/runtime.NzCompressed: u    → z	 messageszRough transcript estimate: ~u    → ~z tokenszFocus: )headline
token_linenoteu(   [CONTEXT COMPACTION — REFERENCE ONLY] r   r  r  rI   zCompression completed.reference_message)ro   r?   )original_messagescompressed_messagesbefore_tokensafter_tokensr  r  rS  r  s          r   &_fallback_summarize_manual_compressionzH_handle_session_compress.<locals>._fallback_summarize_manual_compression*  s    +7+C<<IqIq  sF  JG  JGLic*;&<&<iicJ]F^F^iiiH$j]jjUajjj3>H/+///D G-h - -<(- - --4[[-@-@H76?T))bJ ++ '( Nr   c                 ^    	 ddl m}  ||           S # t          $ r  |           cY S w xY w)Nr   )estimate_messages_tokens_rough)r_  r&  r[   )r2  r&  r  s     r   _estimate_messages_tokens_roughzA_handle_session_compress.<locals>._estimate_messages_tokens_rough*  sb    FOOOOOO55d;;; F F F??EEEEEFs    ,,c                 l    	 ddl m}  || |||          S # t          $ r  | ||||          cY S w xY w)Nr   )summarize_manual_compression)!agent.manual_compression_feedbackr)  r[   )r   r!  r"  r#  r  r)  r$  s         r   _summarize_manual_compressionz?_handle_session_compress.<locals>._summarize_manual_compression*  s    ZZZZZZ33%'! 	      ==%'!     s    33r  r5  r  re  r  r,  z3resolve_runtime_provider failed for compression: %sr  z*No provider configured -- cannot compress.r=  r>  r?  r  Tr  )current_tokensr  )r  z>Session stream state changed during compression; please retry.z6Session was modified during compression; please retry.F)auto_compressionr   rY  r  r  r  compression_anchor_visible_idxcompression_anchor_message_key)r  r  r:  r=  r>  r?  r.  r/  )r  rA   rS  r  z%Manual session compression failed: %sr  r;   )7r%  rh   r&  r   r?   r   r   r   r@   r+  r  r  ro   r`  r  r  r  r  runtime_providerr  r  r  r  r  r[   r   r~  r=   r   r  ra  r@  r  r  r	  context_compressorr  r  r
  r  r:  r=  r>  r?  r   r  r.  r/  r>   compression_anchor_summaryrJ  r,  r  r(  r+  )&r6  r   r  r  r  r   r   r  r   r  r  r'  r+  r<  r  _runtime_provider
_run_agentresolved_modelresolved_providerresolved_base_urlresolved_api_keyr  r  r  r  r   original_stream_stateapprox_tokensr  
compressed
new_tokensrS  current_stream_statevisible_aftersummary_textsession_payloadr  r$  s&                                       @@r   r"  r"  E*  s   S S S.  *	 	 	$l#### $ $ $7CFF########$ dhh|$$*
+
+
1
1
3
3C 674555 dhh}--H'1B1BHbIIOOQQRVSVRVW_[_K6 6 6 67/555556 q$d++ e7^`cdddOI<<<<<<--aj99x==1w abbb	! 	! 	!.	 	 	 	 	 	"	F 	F 	F 	F 	F 	 	 	 	 	 	2 	"!!!!!NNNNNN??????&&&&?C?Z?Z,,QWgaAQSW6X6XYY@
 @
<)+<  	VBB!:+  C  #wwy11$ 8$'GGJ$7$7!$ 8$'GGJ$7$7! 	V 	V 	VNNPRTUUUUUUUU	V '-- 	-2C2N2Ny2Y2Y 	- $ G GHY Z ZGX# + +#* $ - -$,! 	Nw LMMM !NNA)400A-t44M'!%:DAABBA+T22	!
 878IJJ"" &&$ 244 # 
 
 -66(# 7 
 


 54Z@@
//#
 
 
 ))#.. 	 	 -t441488ga)>EEFF/66	$  $'<<<7$dfijj	 	 	 	 	 	 	 	 *)!*559JJJ7$\^abb	 	 	 	 	 	 	 	 $AJ!+AAL!%A%)A"$&A!#'A 7
UZ[[[MQ^/hs1c-6H6H16L/M/M/MdhA,Yf/p/B/B=QSCT/U/U/UlpA,L'4(( x&{{+>??w7;;|C\C\w`g`k`klv`w`w+@+@T B B: N NTRT, ,A( FFHHH=	 	 	 	 	 	 	 	 	 	 	 	 	 	 	@ .IIKKJl$%$6()(>'('<&'&:29!=]_c2d2d29!=]_c2d2d	 	 	
 
 *"*	 
 
 	
  I I I>BBB7G?13E3EGGHHHHHHHHIs    
AA
A
A0D   DD8X =A.X ,AI X 
I1I,'X ,I11A"X C$X 8A+U9#X 0$U9X !DU9-X 9U==X  U=B X 
Y:YYYc                    	 t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY wt          |                    d          pd                                          }|st          | d          S |                    d          }|8	 t          |          }n'# t          t          f$ r t          | d          cY S w xY wddlm	}m
}  |||	          }t          | d
||||k    d          S )zReturn conversation-round count for a gateway session.

    Request body::

        { "session_id": "...", "since": <unix_ts_or_iso> }

    Response::

        { "ok": true, "rounds": 12, "threshold": 10, "should_show": true }
    r5   NrI   r/  rn
  'since must be a unix timestamp (number)r   )count_conversation_roundsCONVERSATION_ROUND_THRESHOLDrn
  T)r  rounds	thresholdshould_show)r%  rh   r&  r   r?   r   r  r  rG  rC  rD  r(  )r6  r   r   r   rn
  rC  rD  rF  s           r   r#  r#  g+  sh   $l#### $ $ $7CFF########$ dhh|$$*
+
+
1
1
3
3C 674555HHWE	K%LLEE:& 	K 	K 	Kw IJJJJJ	K SRRRRRRR&&s%888FW1!==	    s)    
A?AA'B7 7!CCchannelrF  c                    t          j                     }ddd||t          j        d| t          |pd                                          t          |pd                                          pd|t          |          |dd          d	S )
z<Build a compact tool-role transcript marker for persistence.r  rI   handoff_summaryTN)_handoff_summary_cardr5   rS  rI  rF  r
  generated_atFr  )r  tool_call_idr   r  r  r   )rK  r  r  r   r   r  )r   rS  rI  rF  r
  r  s         r   #_build_handoff_summary_tool_messagerP  +  s     )++C !:%)7=b))//11GMr**0022:dX
 
     r   r   c           	         t          | t                    sdS |                     d          dk    s|                     d          dk    rdS |                     d          }t          |t                    r|}n)	 t          j        |pd          }n# t
          $ r Y dS w xY wt          |t                    r|                    d          sdS |                    d	          dS t          |                    d	                    t          |                    d
d                    |                    d          |                    d          t          |                    d                    ddS )zJReturn a normalized handoff-summary payload if *message* is a tool marker.Nr  r  r   rK  r   rI   rL  r5   rS  rI  rF  r
  T)r5   rS  rI  rF  r
  rL  )r=   r>   r?   r  r  r[   r   r  )r   r   r   s      r    _extract_handoff_summary_payloadrR  +  sm   gt$$ t{{6f$$F(;(;?P(P(Ptkk)$$G'4   	jB//GG 	 	 	44	 gt$$ GKK8O,P,P t{{<  (t'++l3344w{{9b1122;;y))++h''Z0011!%  s   :B 
BBr  c                 Z   t          |           }t          |          }|r|sdS |                    d          |                    d          k    o|                    d          |                    d          k    o|                    d          |                    d          k    o|                    d          |                    d          k    oW|                    d          |                    d          k    o+|                    d          |                    d          k    S )zIReturn True when two message payloads represent the same handoff summary.Fr5   rS  rI  rF  r
  rL  )rR  r?   )r  r  r  target_payloads       r   $_is_matching_handoff_summary_messagerU  +  s4   7AA5f==N > u\**n.@.@.N.NN 	eY''>+=+=i+H+HH	eY''>+=+=i+H+HH	e 	X&&.*<*<X*F*FF	e 	Z((N,>,>z,J,JJ		e
 	4559K9KLc9d9ddr   r   rT  c                 @   |dS 	 t          j        | pd          }n# t          $ r Y dS w xY wt          |t                    sdS |                    d          dS |                    d          du o+t          |                    d                    t          |                    d                    k    ot          |                    dd                    t          |                    dd                    k    o|                    d          |                    d          k    oq|                    d	          |                    d	          k    oEt          |                    d
                    t          |                    d
                    k    S )zKReturn True if DB content JSON matches an expected handoff summary payload.NFrI   r5   rL  TrS  rI  rF  r
  )r  r  r[   r=   r>   r?   r   r  )r   rT  r   s      r   $_is_matching_handoff_summary_contentrW  +  s   u*W]++   uugt$$ u{{<  (u+,,4 	NGKK%%&&#n.@.@.N.N*O*OO	NGKK	2&&''3~/A/A)R/P/P+Q+QQ	N 	I."4"4Y"?"??	N 	H!3!3H!=!==		N
 	W[[$$%%n.@.@.L.L)M)MMs    
++c                 \   	 ddl m}  ||           }n# t          $ r Y dS w xY w	 |j        rt	          |j        d         |          rdS |j                            |           |                                 dS # t          $ r'}t          	                    d| |           Y d}~dS d}~ww xY w)zAPersist a handoff summary marker into a local WebUI session file.r   r<  FrY  Tz@Failed to persist handoff summary marker in local session %s: %sN)
rG  r   r   r  rU  r   rJ  r[   r   r~  )r   r   r   r   r   s        r    _persist_handoff_summary_locallyrY  +  s    ******K   uu: 	>qz"~wWW 	4	
'"""	t   Y[^`abbbuuuuus)    
"""A: 
.A: :
B+B&&B+c           
      B   ddl }	 ddl}n# t          $ r Y dS w xY w	 ddlm} t           |                                                                                      }ns# t          $ rf t           |j	        dt          t          j                    dz                                                                                                }Y nw xY w|dz  }|                                sdS |                    dt          j                              }|                    d	d
          }t          |t                    st!          j        |d          }t%          |          }		 t'           |j        t          |                              5 }
	 |	Q|
                    d| f          }|                                }|$t/          |d         |	          r	 ddd           dS n+# t          $ r t0                              d|            Y nw xY w|
                    d| ||f           |
                    d| f           |
                                 ddd           n# 1 swxY w Y   dS # t          $ r'}t0                              d| |           Y d}~dS d}~ww xY w)zPersist a handoff summary marker into CLI sessions state.db.

    This keeps summary cards available after hard-refresh for imported gateway
    sessions that are not in local session JSON yet.
    r   NFrT   rX   rY   zstate.dbr  r   rI   rN  z_SELECT content FROM messages WHERE session_id = ? AND role = 'tool' ORDER BY rowid DESC LIMIT 1Tz7Unable to read tail handoff marker from state.db for %szTINSERT INTO messages (session_id, role, content, timestamp) VALUES (?, 'tool', ?, ?)zOUPDATE sessions SET message_count = COALESCE(message_count, 0) + 1 WHERE id = ?z?Failed to persist handoff summary marker in state.db for %s: %s)r]   r  rt
  rZ   rU   r   r`   re   r[   r^   r   r_   rz   r?   rK  r=   r  r  rR  r   r  r  r  rW  r   r   commitr~  )r   r   r]   r  rU   r2  r  r  r   marker_payloadr  r  ri  r   s                 r   $_persist_handoff_summary_to_state_dbr]  ,  sK    III   uuj777777113344??AAIIKK j j j929]C	i8O4P4PQQRR]]__ggiij J&G>> u	[$)++	.	.Bkk)R((Ggs## :*W59995g>>N!_W_S\\2233 	t]!-,,6 C
 ,,..C+OPSTUPVXf+g+g#	 	 	 	 	 	 	 	  ] ] ]VX[\\\\\] LL+gr"   LL  
 KKMMM9	 	 	 	 	 	 	 	 	 	 	 	 	 	 	: t   XZ]_`aaauuuuus    
AA A-CC%*I- I AG%I- $I %%H
I HAI I-  I$$I- 'I$(I- -
J7JJc                     t          | ||||          }t          |           }|r"t          | |           t          | |           |S t          | |          }|r|S t          | |          r|n|S )z?Persist a handoff summary marker across local/session backends.)rP  r  r]  rY  )r   rS  rI  rF  r
  markerr  persisted_locals           r   _persist_handoff_summaryra  D,  s    0gwPXYYF3C88 ,S&999(f5556sFCCO 9#vFFR66FRr   c                 @  ,-./01 	 t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY wt          |                    d          pd                                          00st          | d          S |                    d          }|8	 t          |          }n'# t          t          f$ r t          | d          cY S w xY wddlm	}m
}m}  |0|	          }||k     rt          | d
d          S  |0          }|ddl}	g }
|D ]}|                    d          }|	 t          |t          t          f          rt          |          }nM|	j                            t          |                              dd                                                    }||k    r|
                    |           # t&          $ r Y w xY w|
}n|}|dd         }t)          |          dk     rt          | dd          S d .d -t+          -.fd|D                       1g }|D ]|}|                    dd          } .|                    d                    }t          |pd                                          dd         }|dv r|r|                    |           }d                    |          }.1fd}d //fd,0fd}d7,/fd	}	 ddlm} dd lm} ddlm} ddl}d}d}d}	 dd!lm}  |0          }t?          |d"d          }n# t&          $ r Y nw xY w|                     |          \  }}}d}	  ||j!        |#          } |                     d$          }|s|                     d%          }|s|                     d&          }n2# t&          $ r%}!tD          #                    d'|!           Y d}!~!nd}!~!ww xY wt          |t                    r9|$                    d(          r$|%                    |          \  }"}#|s|"r|"}|s|#r|#}|s\ ||          }$	 tM          0|$ |            |d)*           n# t&          $ r Y nw xY wtO          | d)|$t)          |          |d)d+          S |(                    ||||d,d)g 0-          }%d.}&d/| }'	  ||%|&|'d0          }(t          |(tR                    r|(                    d1          nd}$ ,|(          rW ||%|&|'d20          })t          |)tR                    r|)                    d1          nd}$ ,|)          r ||          }$d)}*nd3}*nd3}*	 |%*                                 n:# t&          $ r Y n.w xY w# 	 |%*                                 w # t&          $ r Y w w xY wxY w|$s ||          }$d)}*n /|$          r|*sd)}* |            }+tM          0|$|+||**           tO          | d)|$t)          |          ||*d+          S # t&          $ r}tD          #                    d4|            ||          }$	 tM          0|$ |            |d)*           n# t&          $ r Y nw xY wtO          | d)|$t)          |          |d)d5tW          |           d6          cY d}~S d}~ww xY w)8aG  Generate an on-demand handoff summary for a gateway session.

    Request body::

        { "session_id": "...", "since": <unix_ts_or_iso> }

    Uses the session's configured model to produce a concise summary of
    recent conversation activity.  Returns the summary text so the caller
    can display it in a tool-card.
    r5   NrI   r/  rn
  rB  r   )r  rC  rD  rE  z5Not enough conversation rounds to generate a summary.r  r  r  r  ir  z!Not enough messages to summarize.c                     t          | t                    r1d                    d | D                                                       S t	          | pd                                          S )Nr3  c              3      K   | ]R}t          |t                    t          |                    d           p|                    d          pd          V  SdS r  r  rv   s     r   rx   zI_handle_handoff_summary.<locals>._extract_handoff_text.<locals>.<genexpr>,  sn        a&&AEE&MM;QUU9%5%5;<<     r   rI   )r=   ra  r  r   r   )raw_contents    r   _extract_handoff_textz6_handle_handoff_summary.<locals>._extract_handoff_text,  sr    k4(( 	88  $     egg	
 ;$"%%++---r   c                 N    t          d t          |           D                       S )Nc              3   6   K   | ]}d |cxk    odk    nc V  dS )u   一u   鿿Nr   r:	  s     r   rx   zE_handle_handoff_summary.<locals>._contains_chinese.<locals>.<genexpr>,  s>      BB"8r----X----BBBBBBr   )r   r   )r.  s    r   _contains_chinesez2_handle_handoff_summary.<locals>._contains_chinese,  s%    BBD		BBBBBBr   c              3   f   K   | ]+}  |                     d                               V  ,dS )r   Nr   )r   r  ri  rf  s     r   rx   z*_handle_handoff_summary.<locals>.<genexpr>,  sZ           	//i0@0@AABB           r   r  r   r  r  r  r   c                    g }g }dd}| D ]w}|                     dd          } | |                     d                    d          }|dv r3|r1|dk    r|                    |           b|                    |           x|s|s	rd	nd
S 	rg }|r|                    d|d          d           |r|                    d|d          d           t          |          t          |          z   dk    r|                    d           n|                    d           d                    |          S g }|r|                    d|d          d           |r|                    d|d          d           t          |          t          |          z   dk    r|                    d           n|                    d           d                    |          S )zJReturn a deterministic summary when LLM summary generation is unavailable.N   c                    d                     t          | pd                                                                                    }|sdS t	          |          |k    r|S |d |dz
                                           dz   S )Nr3  rI   r   r  )r  r   r   r   ro   rc  )r  r  r.  s      r   _summarize_snippetzV_handle_handoff_summary.<locals>._fallback_handoff_summary.<locals>._summarize_snippet,  s~    88CB//557788>>@@D r4yyG##'A+&--//%77r   r  rI   r   R   rk  r  uc   近期可读文本不足，无法生成更完整的交接摘要，请补充一条消息后重试。zdNot enough readable text to create a useful handoff summary; please send one more message and retry.u   - 你刚讨论了：rY  u   。u   - 助手已回复：r  u2   - 当前对话存在尚未确认的后续动作。u;   - 当前信息偏少，建议补充关键点后再切换。r   z- You asked: r$  z- The assistant responded: z,- There is pending context to continue next.zH- The conversation is still short; add one more turn before summarizing.)rm  )r?   r   ro   r  )
r  user_pointsassistant_pointsro  r  r  r   bulletsrf  transcript_is_chineses
           r   _fallback_handoff_summaryz:_handle_handoff_summary.<locals>._fallback_handoff_summary,  s[   	8 	8 	8 	8  	5 	5A55$$D(()>)>quuY?O?O)P)PRTUUG,,,,6>>&&w////$++G444 	#3 	 )|uu{ ! 
	&G LJk"oJJJKKK QO6Fr6JOOOPPP;#&6"7"771<<STTTT\]]]99W%%% 	?NN=;r?===>>> 	RNNP9I"9MPPPQQQ{c"2333q88NNIJJJJNNefffyy!!!r   c                    t          | t                    st          | pd          } |                                 } | sdS |                     d          s|                     d          rdS d |                                 D             }|sdS |d         }t          j        d|          rdS t          |          d	k    r"t          j        d
|t
          j                  sdS t          t          j        d|t
          j                            S )zKBest-effort guard for truncated summaries when LLM signals are unavailable.rI   Tr   r  c                 ^    g | ]*}|                                 |                                 +S r   r  )r   r   s     r   r{   zO_handle_handoff_summary.<locals>._summary_output_incomplete.<locals>.<listcomp>,  s-    LLL$tzz||LLLLr   rY  u   [。！？；!?.；]$F8   z/\b(and|or|so|then|because|if|when|but|so|as)\b$z"\b(and|or|but|so|because|if|when)$)
r=   r   r   r  r  r  r  ro   rd	  r  )r.  r  	last_lines      r   _summary_output_incompletez;_handle_handoff_summary.<locals>._summary_output_incomplete,  s   $$$ 	#tzr??Dzz|| 	4== 	4==#7#7 	4LL$//*;*;LLL 	4"I	9-y99 	5y>>R	2dfoqsq~((4BICYPRP]^^___r   c                 x   t          | t                    sdS |                     d          pd                                                                }|dk    rdS |                     d          pd                                                                }|dv rdS  |                     dd                    S )NTfinish_reasonrI   r  stop_reason>   r  
max_tokensr.  )r=   r>   r?   r   r   )summary_resultr9   r}  rz  s      r   _agent_summary_incompletez:_handle_handoff_summary.<locals>._agent_summary_incomplete,  s    .$// 	4 $$_55;BBDDJJLLX4%))-88>BEEGGMMOO2224)).*<*<VR*H*HIIIr   c                     d } 	 ddl m}m}  |          }|j        p|j        p|j        p|j        } | s| |            D ]q}|                    d          k    rV|                    d          p>|                    d          p)|                    d          p|                    d          }  nrn# t          $ r Y nw xY w| S )Nr   )r   rt  r5   r  r%  r~  r4   )	rG  r   rt  r  r%  r~  r  r?   r[   )channel_labelrM  rt  session_metarc   r   s        r   _resolve_handoff_channel_labelz?_handle_handoff_summary.<locals>._resolve_handoff_channel_label,  s"   	PPPPPPPP'<,,L) /*/*/  .	  ! 	!1!1!3!3  I }}\22c99%MM.99 7(}}\::7(}}\::7  )}}X66	 &  :  	 	 	D	s   B-B3 3
C ?C   c                    d|dd|dg}ddddd}dd	i}t          | d
d          }	 || _        t          | dd          dk    r|                     |          }|                    dd           ||d<   |                     |          }	|                     |	          \  }
}t          |
r	|
j        pdnd                                          |d<    |d                   |d<   ||| _        S t          | dd          dk    rddl	m
}m}  || j        |d||t          | dd	          |                                 t          | dd                    }|                     |          }	 ||	t          | dd	                    \  }
}t          |
r	|
j        pdnd                                          |d<    |d                   |d<   ||| _        S |                     |          }|                    dd           d|d<   d|d<   d|v r||d<   n||d<    |                     d          j        j        j        d%i |}	t          |	d d          pdgd         }|t          |d!d          nd}t          t          |d"d          pd                                          |d<   t          |d#d          |d#<   t          |d$d          |d$<    |          |d<   ||| _        S # || _        w xY w)&zMUse the current Hermes Agent transport without mutating conversation history.r  r  r  rI   NT)r.  r|  r}  
incompleter  Freasoning_configapi_modecodex_responsestoolsmax_output_tokensr.  r  anthropic_messagesr   )build_anthropic_kwargsnormalize_anthropic_response_is_anthropic_oauth_anthropic_base_url)r  r  r  r~  r  is_oauthpreserve_dotsr,  )strip_tool_prefixg?temperaturer  r  max_completion_tokensr~  rK  r@  r  r   r   r|  r}  r   )r@   r  _build_api_kwargsrP  _run_codex_stream_normalize_codex_responser   r   r   agent.anthropic_adapterr  r  r  _anthropic_preserve_dots_anthropic_messages_create_ensure_primary_openai_clientr  r  r  )r  rm  	user_textr~  api_messagesr   disabled_reasoningprevious_reasoningcodex_kwargsr0  assistant_messager   r  r  
ant_kwargs
api_kwargsr  r  r  rz  s                     r   _agent_text_completionz7_handle_handoff_summary.<locals>._agent_text_completion-  s    -88	22

 !	
 
 (/$U,>EE5	8%7E"uj"--1BBB$66|DD  $///4>01..|<<','F'Ft'L'L$!1!$J[%c&7&?&E2ac!d!d!j!j!l!lv'A'A&.'Q'Q|$V &8E""S uj"--1EEEhhhhhhhh33+))%7$U,A5II"'"@"@"B"B$U,A4HH	 	 	
 77
CC'C'C&-e5JE&R&R( ( ($!1 "%J[%c&7&?&E2ac!d!d!j!j!l!lv'A'A&.'Q'Q|$* &8E""' 00>>JNN7D)))(+J}%$(Jy!&*446@
233+5
<(h566>O6PPUah   D dIt44>BF6<6H'&)T222dC i!<!<!BCCIIKKF6N&-fot&L&LF?#$+FM4$H$HF=!#<#<V#D#DF< %7E""%7E"7777s   B=K% .CK% D
K% %	K.r  r<  r  r  re  r  r,  z7resolve_runtime_provider failed for handoff summary: %sr  T)r
  )r  rS  r  rF  r
  r  r  us  You are summarizing an external-channel conversation so a Web UI reader can quickly catch up after switching contexts.

Only use the latest messages, and never copy raw transcript lines.
Do not output role labels (no “你:” / “assistant:” / “user:” / “assistant”).
Use direct 2–5 bullet points in the conversation language.
English: speak using “you”.
中文: 使用“你”。

Focus on:
- Unfinished tasks or action items
- Pending questions that need replies
- Key decisions made
- Open disagreements or TBD items

If the conversation is purely casual with no actionable items, say so in one sentence.zConversation transcript:
)r~  r.  ix  Fz%Handoff summary generation failed: %sz(Summary generation used local fallback: )r  rS  r  rF  r
  r~  )r  ),r%  rh   r&  r   r?   r   r  r  rG  r  rC  rD  r  r=   r  rs
  r%  r  r   r[   ro   r   r  r`  r  r  r  r  r0  r  r   r@   r  r  r   r~  r   r  ra  r(  r  r>   release_clientsr+  )2r6  r   r   rn
  r  rC  rD  rF  all_msgs_dtr  r  ts_rawts_valr2  r  r  r   
transcriptru  r  r  r<  r  r3  r4  r5  r6  r7  r   s_objr8  r  r  r  r  r?  r  summary_system_promptsummary_user_text
first_passsecond_passr
  r  r  ri  rf  rz  r   rt  s2                                               @@@@@@r   r$  r$  R,  s"
   $l#### $ $ $7CFF########$ dhh|$$*
+
+
1
1
3
3C 674555HHWE	K%LLEE:& 	K 	K 	Kw IJJJJJ	K mlllllllll&&s%888F,,,7SUXYYY (',,H 	 	AUU;''F~
fsEl33 ""6]]FF \77F++C:: ikk  E>>OOA&&&    :D
4yy1}}7?EEE. . .C C C                   
 E " "uuVR  ''i(8(899gm$$**,,UdU3(((W(LL!!!5!!J1" 1" 1" 1" 1" 1"f` ` `&	J 	J 	J 	J 	J    4C8 C8 C8 C8 C8 C8 C8L`!!!!!!NNNNNN??????&&&&   	......K$$E$UGT::NN 	 	 	D	 @D?Z?Z[i?j?j<)+<	ZBB!:+  C  #wwy11$ 8$'GGJ$7$7!$ 8$'GGJ$7$7! 	Z 	Z 	ZNNTVXYYYYYYYY	Z '-- 	-2C2N2Ny2Y2Y 	- $ G GHY Z ZGX# + +#* $ - -$,! 	44T::L	( 2244!        W'!$T       "" &&$ # 	
 	
& 	  FEE	//%!	  J 6@
D5Q5QY:>>&111WYL((44 !44)%#	   ;E[RV:W:W_{v666]_,,[99 %#<#<T#B#BL#HH$HH %%''''   %%''''    	 44T::LHH''55 	   6688 	
 	
 	
 	
 # YY 
 
   	    >BBB0066		$..00      	 	 	D	# YYV/RSBTBTVV
 
   	 	 	 	 	 	sV   
A
AA
A
-B= =!C! C!BG
G$#G$-X 
"L- ,X -
L:7X 9L::X AN/ .X /
O9OX OAX =Q X 
Q'$X &Q''%X $X 2BU7 U' &X '
U41X 3U44X 7V9VV
VVVVA"X 
Z&Z2YZ
YZY6ZZZc                 n   	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w|d                                                                                             dd          }|rd|v sd|v rt          | d          S |                    dd	                                          }|rd|v sd|v rt          | d
          S t                      }|r	||z  |z  }n||z  }	 |	                                
                    |	                                           n # t          $ r t          | d          cY S w xY w|                    dd           |dz  }|                    |d         d           t          | d|t          |          d          S )Nr   r   r3  r#  r   r	  r  r   rI   zInvalid categoryzInvalid skill pathTr   r   r   r   )r  r   r    )r%  rh   r&  r   r   r   r%  r?   ra   re   rf   r   r  r(  )r6  r   r   
skill_namer   rp   r   
skill_files           r   rN  rN  -  s   $fi(((( $ $ $7CFF########$f##%%++--55c3??J 2
**dj.@.@70111xx
B''--//H 0SH__(8(87.///#%%J ,)J6		+	2''
(:(:(<(<==== 2 2 270111112OOD4O000Z'J$y/G<<<WT:s:OOPPPs+    
AA A A9D= =EEc                 p   	 t          |d           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY wdd l}t          |d                                                                                                       dd          rdv sdv rt          | d          S t                      }fd|	                    d	          D             }|st          | d
d          S |d         j
        } |j        t          |                     t          | d|d         d          S )Nr   r   r3  r#  r   r	  r  c                 4    g | ]}|j         j        k    |S r   )r   r   )r   rw   r  s     r   r{   z(_handle_skill_delete.<locals>.<listcomp>&.  s'    VVVQ!(-::U:Uq:U:U:Ur   r   r  r4  T)r  r   )r%  rh   r&  r   r  r   r   r%  ra   r   r   r   r(  )r6  r   r   r  rp   matchesr   r  s          @r   rO  rO  .  s[   $f $ $ $7CFF########$MMMT&\""((**0022::3DDJ 2
**dj.@.@70111#%%JVVVV***:66VVVG 47-s333
!IFM#i..!!!WT4<88999s    
AA A Ac                     | g S t          | t                    r| g} n(t          | t                    s| rt          |           ng } t          t                              d | D                                 S )zFNormalize a config value (None/str/list) into a deduplicated str list.Nc              3      K   | ]F}t          |                                          #t          |                                          V  Gd S r;   r+  )r   ds     r   rx   z(_normalize_names_list.<locals>.<genexpr>6.  sC      NNs1vv||~~Nc!ffllnnNNNNNNr   )r=   r   ra  r>   fromkeys)rv  s    r   _normalize_names_listr  ..  sv    }	% -t$$ -$,U"NNeNNNNNOOOr   r  c                 x    t          |           } |rfd| D             S | vr|                                | S )z8Add or remove *name* from *names*, returning a new list.c                      g | ]
}|k    |S r   r   )r   r  r   s     r   r{   z(_toggle_name_in_list.<locals>.<listcomp>=.  s    ...aAIIIIIr   )r  r   )rv  r   r  s    ` r   _toggle_name_in_listr  9.  sT    !%((E /....5....5TLr   c                    	 t          |dd           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY w|d                                         }t          |d                   }t                      }t          |          }t          ||          \  }}|st          | d| dd          S t                      }	t          5  t          |	          }
d|
vst          |
d         t                    si |
d<   |
d         }t          |                    d          ||          |d<   |                    d	          }t          |t                    rd
|v rt          |d
         ||          |d
<   ||
d<   t!          |	|
           ddd           n# 1 swxY w Y   t#                       t%          | d||d          S )aS  Toggle a skill's enabled/disabled state in the active profile's config.yaml.

    Writes through to ``skills.platform_disabled.webui`` when that key exists
    so the toggle takes effect for WebUI sessions (the agent's
    ``get_disabled_skill_names`` checks platform-specific lists first when
    ``HERMES_SESSION_PLATFORM`` is set).
    r   r  Nr   ' not foundr4  rV   r   platform_disabledr  Tr  r   r  )r%  rh   r&  r   r   r  ra   r   r   r   r$  r!  r=   r>   r  r?   r"  r#  r(  )r6  r   r   r   r  rp   r   r   rj   config_pathr  
skills_cfgr  s                r   rP  rP  C.  s>   $fi(((( $ $ $7CFF########$ <D4	?##G $%%J+J77K-dK@@Ix >77d777==="$$K	 1 1$[11 3jX&E&ECM]
 "6NN:&&g"
 "

: 'NN+>??'.. 	7>O3O3O)=!'*D'* *g& #H{C000/1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 OOOWT4GDDEEEs,    
AA A AC FF#&F#c                 6   	 t          |dd           n4# t          $ r'}t          | t          |                    cY d }~S d }~ww xY w	 ddlm}  |            }|dz  }n+# t          $ r t          j                    dz  }|dz  }Y nw xY w|	                    dd           |d         }|d	k    r|d
z  }n(|dk    r|dz  }n|dk    r|dz  }nt          | d          S |
                    |d         d           t          | d|t          |          d          S )Nr  r   r   rT   rw
  rY   Tr   r{
  rx
  r  ry
  r|
  rz
  z+section must be "memory", "user", or "soul"r   r   )r  r  r    )r%  rh   r&  r   rZ   rU   rt
  r   r_   r   r  r(  )r6  r   r   rU   r_   r
  r  r  s           r   rQ  rQ  y.  s~   $i++++ $ $ $7CFF########$$777777%%''# $ $ $y{{Y&#$ MM$M...9oG(;&	F		9$	F			!7IJJJ
d9o888WTgs6{{KKLLLs+    
AA A A	A %BBc                     t          | t                    s| S t          |           }|                    dd           |                    dd           |S )aC  Normalize message payloads for import refresh prefix checks.

    The strict dict comparison previously failed when existing messages held
    integer timestamps while refreshed messages held floating-point timestamps.
    Strip timing keys before comparison so we can safely treat semantic
    prefixes as equivalent.
    r  Nr  )r=   r>   rP  )r   r  s     r   %_normalize_message_for_import_refreshr  .  sT     gt$$ gJNN;%%%NN5$r   c                 H   t          | t                    sdS |                     d          dk    r|                     d          rdS |                     d          dk    rA|                     d          s*|                     d          s|                     d	          rdS dS )
NFr  r  r  Tr  rO  	tool_namer   r  )r   s    r   _message_has_cli_tool_metadatar  .  s    gt$$ u{{6k))gkk,.G.G)t{{6f$$'++n*E*E$U`IaIa$elepepqwexex$t5r   c                     t          | t                    st          |           S t          |           }t          |t                    s|S dD ]}|                    |d            |S )N)r  rO  r  r   )r=   r>   r  rP  )r   r  r8  s      r   $_strip_cli_tool_metadata_for_refreshr  .  ss    gt$$ >4W===6w??Jj$'' B " "sD!!!!r   existing_messagesfresh_messagesc                    t          | t                    rt          |t                    sdS t          |           t          |          k    rdS t          d | D                       rdS t          d |D                       sdS t	          |           D ].\  }}t          |          t          ||                   k    r dS /dS )af  Return True when fresh messages only add CLI tool metadata.

    Older imports from get_cli_session_messages() persisted assistant/tool rows
    without tool_calls, tool_call_id, or tool_name. After #1772 the refreshed
    transcript can have the same length but richer metadata, so re-imports must
    rebuild the stored sidecar even without a new row.
    Fc              3   4   K   | ]}t          |          V  d S r;   r  r6  s     r   rx   z3_is_cli_tool_metadata_enrichment.<locals>.<genexpr>.  s+      
H
H)!,,
H
H
H
H
H
Hr   c              3   4   K   | ]}t          |          V  d S r;   r  r6  s     r   rx   z3_is_cli_tool_metadata_enrichment.<locals>.<genexpr>.  s+      IIQ-a00IIIIIIr   T)r=   ra  ro   r   rc
  r  )r  r  r^  existing_messages       r    _is_cli_tool_metadata_enrichmentr  .  s     '.. jQU6V6V u
^!4!444u

H
H6G
H
H
HHH uII.IIIII u!*+<!=!=  /0@AAEijxy|j}E~E~~~55 4r   c                 "   t          | t                    rt          |t                    sdS t          |           t          |          k    rdS t          |           D ]0\  }}||         }t	          |          t	          |          k    r dS 1dS )a  Return True when existing_messages is a prefix of fresh_messages by value.

    This is a semantic comparison intended for import refresh, not deep
    structural equality. It intentionally ignores timing fields that may differ
    in type/precision between storage layers.
    FT)r=   ra  ro   rc
  r  )r  r  r^  r  fresh_messages        r   !_is_messages_refresh_prefix_matchr  .  s     '.. jQU6V6V u
N 3 333u!*+<!=!=  &s+01ABBFklyFzFzzz55 {4r   c                    	 t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY wt          |d                   }t	          j        |          }|rt          |          }d}d}t          t                                D ]}|d         |k    r|} n|rDt          |          t          |j
                  k    rt          |j
        |          r	||_
        d}n |rt          |j
        |          r	||_
        d}|rd|j        p|                    d          |j        p)|                    d          p|                    d          |j        p|                    d          |j        p|                    d          |j        p|                    d	          d
}	|	                                D ]-\  }
}t)          ||
d          |k    rt+          ||
|           d}.|r%|                    d           t/          d           t1          | |                                |j
        dt5          |pi                     d                    dz  dd          S t          |          }|st          | dd          S d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}t                      D ]}|d         |k    ru|                    d          }|                    dd          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d          }|                    d	          }t5          |                    d                    } n|pt7          |d          }d}t9          ||          rt;                      }|ryi d|d|dt          t=                                d|d t          |          d|d|d!|p|d"dd#dd$dd|d%dd|d|p|d|d||d|g d&} t1          | | dd          S t?          ||||||||'          }!|r||!_         d|!_!        ||!_        |p||!_        ||!_        ||!_        ||!_"        ||!_#        ||!_$        ||!_%        ||!_&        ||!_'        ||!_(        |!                    d           t/          d           t1          | |!                                |dd(z  dd          S ))z1Import a single CLI session into the WebUI store.r5   NFTr~  r%  r  r  r  )r  r~  r%  r  r  r  rF  session_import_clir  )r  r  r  )rA   importedzSession not found in CLI storer4  r  rk  r  r  r  r  r<  r9  r;  r:  r7  r6  r;  r<  r  r  r=  r>  r?  r  )r  r  r  r  )rk  r  r  r  )r  r  ))r%  rh   r&  r   r_  r`  r  ra  rt  ro   r  r  r  r~  r?   r%  r  r  r  r  r@   r  rJ  r   r(  r  r  r  r  r  r  r  r?  r  r<  r9  r;  r:  r7  r6  _cli_origin)"r6  r   r   r   r  
fresh_msgsrh  r  r  r  attrr-  r2  rk  r  r  	cli_titlecli_source_tagr  cli_raw_sourcecli_session_sourcecli_source_labelcli_user_idcli_chat_idcli_chat_typecli_thread_idcli_session_keycli_platformcli_parent_session_idcli_read_onlyr  cron_project_idr@  r   s"                                     r   r\  r\  .  s!   $l#### $ $ $7CFF########$ d< 
!
!C |C  H /
-c22
'))** 	 	B,3&& '  	#j//C0A,B,BBB 11BJOO $.! 	<X=NPZ[[ 	 !+HG 	#"&&1OX\\,5O5O&1mX\\,5O5OmS[S_S_`lSmSm"*"9"[X\\JZ=[=[ ( 5 Un9U9U%-%?%d8<<PcCdCd G  '}} # #e8T400E99HdE222"G 	?MM5M111()=>>>#++-- ( 1&*!%x~2&:&:;&G&G!H!H  " 
 
 	
 $C((D C7<cBBB GJJINENKKMMOL M    ls""ffY''GFF7I..E--J--JwIVVL11NVVL11N!#(8!9!9!vvn55&&++K&&++KFF;//MFF;//M ff]33O66*--L$&FF+>$?$?! !4!455ME% #* 8D-88E OsN++ 0-// K
#
U
 /1122
 U	

 SYY
 *
 *
 z7Z
 e
 
 $
 w
 d
 .
 .:N
  0!
" ,#
$ "7+
 
 
. o5IIJJJ/		 		 		A  '&A!AL!3^AL)A%ANAIAIAKAK#AMAJAMFFEF""" !5666yy{{ "& 
 	
 	

 
 
r8  c           
      z   |rt          |t                    st          | d          S |                    d          }t          |t                    st          | d          S |                    dd          }	 t          t          |                    dt          t                                                  }n;# t          t          f$ r'}t          | t          |                    cY d}~S d}~ww xY w|                    dt                    }t          |||||                    d	g           
          }|                    dd          |_        t          5  |t          |j        <   t          j        |j                   t#          t                    t$          k    r2t          j        d           t#          t                    t$          k    2ddd           n# 1 swxY w Y   |                                 t+          d           t-          | d|                                d|j        iz  d          S )zIImport a session from a JSON export. Creates a new session with a new ID.z"Request body must be a JSON objectr  z$JSON must contain a "messages" arrayr  zImported sessionr<  Nr  r  )r  r<  r  r  r  r=  Fr]  session_importTr  )r=   r>   r&  r?   ra  r   r$  r  r  rh   r   r_  r=  r  r  r5   ra  ro   r  rb  rJ  r   r(  r  r  )r6  r   r  r  r<  r   r  r   s           r   r[  r[  /  sK    Bz$-- B7@AAAxx
##Hh%% D7BCCCHHW011E$1$((;L]H^H^2_2_``aa		z" $ $ $7CFF########$HHWm,,E88L"--	 	 	A xx%((AH	 ) )!"Q\***(mml**%(((( (mml**) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 FFHHH !1222WTaiikkZ<T.TUUVVVs2   9AB< <C4C/)C4/C4A8G  G$'G$)r[  r"  r   r#  c                 8   t          | t                    s| S d}i }|                                 D ]h\  }t          |t                    r!t	          fd|D                       rd|<   ;t          |t                    rt          |          |<   c||<   i|S )z.Mask sensitive values in env vars and headers.)authtokenr8  secretr  
credentialc              3   D   K   | ]}|                                 v V  d S r;   )r   )r   r   rN  s     r   rx   z _mask_secrets.<locals>.<genexpr>/  s/      %H%Ha17799n%H%H%H%H%H%Hr      ••••••)r=   r>   r  r   r   _mask_secrets)obj	sensitivemaskedr  rN  s       @r   r  r  /  s    c4   
LIF		  1a 	#%H%H%H%Hi%H%H%H"H"H 	,F1II4   	%a((F1IIF1IIMr   c                    | dS t          | t                    r| S t          | t          t          f          r| dk    S t          | t                    r2|                                                                 }|dv rdS |dv rdS dS )zBParse Hermes MCP ``enabled`` values without raising on bad config.NTr   >   rJ   rM   rL   rK   >   r  r  r  r  F)r=   r  r  r  r   r   r   )r-  r  s     r   _parse_mcp_enabledr  /  s    }t% %#u&& z% [[]]((**
333444454r   c                      	 ddl m}   |             }n# t          $ r i cY S w xY wt          |t                    si S d |D             S )a/  Return already-known MCP runtime status without starting servers.

    ``tools.mcp_tool.get_mcp_status()`` only reads the existing MCP registry and
    configuration; it does not probe or spawn MCP subprocesses. If Hermes Agent
    is unavailable, fall back to an empty map so the API remains safe.
    r   )get_mcp_statusc                     i | ]O}t          |t                    |                    d           ,t          |                    d                     |PS r   r  )r   r1  s     r   rS  z/_mcp_runtime_status_by_name.<locals>.<dictcomp>/  sd       eT"" (-yy'8'8EIIf  r   )tools.mcp_toolr  r[   r=   ra  )r  statusess     r   _mcp_runtime_status_by_namer  /  s    111111!>##   			h%% 	    s    ""c           
      \   t          |t                    r|ni }d| i}t          |t                    s|                    dddddddd           |S t          |                    d	d
                    }|r"t          |                    d                    nd}d|v r-d|d<   d|v rt          |d                   |d<   |d         |d<   nad|v rTd|d<   |                    dd          |d<   |                    dg           |d<   d|v rt          |d                   |d<   n	d|d<   d}d}|                    dd          |d<   |                    dd          |d<   ||d	<   ||d<   |d         dk    rd|d<   n|sd|d<   n|rd|d<   nd|d<   |r|                    d          nd|d<   |S )z.Return a safe summary of an MCP server config.r   r  r  r(   Finvalid_configN)	transportr  connect_timeoutr  rR  r  
tool_countr  T	connectedurlhttpr  r  r  stdiorI   r  envr  r  rR  r  r   r  r  r  )r=   r>   r	  r  r?   r  r  )r   r  runtime_statusoutr  r  s         r   _server_summaryr  /  s   '1.$'G'GO^^RN4.Cc4   


"!&
 
 	 	 	 
 D!9!9::G9@K^''44555eI||!K*3y>::C	NZE

	c		"KB//Iggfb))FC<<&s5z22CJ$K	WWY,,C	N WW%6;;CC	NCM
;9$$(H %"H	 % H$H7EO**73334CJr   c                b   t          | t                    s| dnt          |           } t          |                                           } t	          j        dd| t          j                  } t          |           |k    r0| dt          d|dz
                     	                                dz   } | S )	z@Return redacted, bounded MCP text safe for WebUI inventory rows.NrI   zAuthorization:\s*Bearer\s+\S+z[REDACTED CREDENTIAL]rb	  r   r   r  )
r=   r   r-  r   r  r  rV
  ro   r  rc  )r-  r`  s     r   _mcp_safe_display_textr  0  s    eS!! 4mU%%''EF35Le[][_```E
5zzE)Auqy)))*1133e;Lr   c                 v   t          | t                    sdS |                     d          }t          |t                    rd                    d |D                       }t          |t
                    r|r|S dD ]6}t          |                     |          t                    r| |         r|c S 7d| v rdS dS )zDReturn a compact, non-sensitive display type for a JSON schema node.r  r  r   c              3   8   K   | ]}|t          |          V  d S r;   r  rt  s     r   rx   z#_mcp_schema_type.<locals>.<genexpr>.0  s-      00!a0s1vv000000r   )anyOfoneOfallOfenumr  )schematyp	composites      r   _mcp_schema_typer  (0  s    fd## y
**V

C#t 1hh00s00000#s  
0  	fjj++T22 	vi7H 	v9r   r[  c                   t          | t                    sg S |                     d          }t          |t                    sg S |                     d          }t          |t                    rt	          |          nt	                      }g }|                                D ]\  }}t          |          |k    r nt          |t                    s0t          |t                    r|ni }|                    dd          }t          |t                    sd}t          |d          }|	                    |t          |          ||v |d           |S )aV  Summarize an MCP input schema without exposing raw defaults/examples.

    The WebUI only needs searchable/displayable argument hints. Returning raw
    JSON Schema can overexpose server-provided defaults, examples, enums, or
    vendor extensions, so this strips each parameter down to name/type/required
    and a redacted description.
    
propertiesrequiredr   rI      r  )r   r  r  r   )r=   r>   r?   ra  r   r  ro   r   r  r   r  )	r  r`  r  r  required_namesr  r   propr?  s	            r   _mcp_schema_summaryr!  90  s^    fd## 	L))Jj$'' 	zz*%%H&04&@&@KS]]]ceeN
C &&((  
ds88uE$$$ 	!$--5tt2xxr**$$$ 	D%d#666

$T**.	
 
 	 	 	 	 Jr   c                 
   t          | t                    si S dD ]h}|                     |          }t          |t                    r<|dk    r2t          |                    d          t                    r
|d         c S |c S ii S )N)
parametersinputSchemainput_schemar  r  r#  r  )r  r8  r-  s      r   _mcp_tool_schema_from_payloadr&  \0  s    dD!! 	F  eT"" 	h:eii.E.Et#L#L\****LLL	 Ir   c                    t          |t                    r|ni }t          |t                    rd|i}nt          |t                    si }t          |                    d          p| pd          }|                    d          pd}t          |t                    st          |          }t	          |d          }|t          |                    d          pd          |t          |                    d                    t          |                    d                    |                    d          pd	t          t          |                    d
S )z4Return a safe global inventory row for one MCP tool.r   rI   r   ih  r  rR  r  r  r  )r   rg  r   rR  r  r  schema_summary)r=   r>   r   r?   r  r  r!  r&  )r   r  server_summaryr  r   s        r   _mcp_tool_summaryr*  h0  sG   '1.$'G'GO^^RN$ ~d## DHHV$$2233I((=))/RKk3'' '+&&(C@@@Kn((006B77"~))(3344**95566 $$X..;)-.KD.Q.QRR  r   c                 :   g }t          | t                    s|S |                                 D ]\  }}t          |t                    s|                    d          }t          |t                    s|                    d          }t          |t                    sp|                    t          |          dt          |          i          }t          |          D ]:\  }}| d| }	t          |	||          }
|
d         r|                    |
           ;|S )zCRead detailed MCP tool payloads from runtime status when available.r  tool_schemasr   r   )	r=   r>   r  r?   ra  r   rc
  r*  r   )runtime_by_nameserver_summariesr  server_nameruntime	raw_toolsr)  r  r  fallback_namerS  s              r   _mcp_tools_from_runtime_statusr3  0  s0   Eot,,  / 5 5 7 7 & &W'4(( 	KK((	)T** 	4N33I)T** 	)--c+.>.>[IYIY@Z[[$Y// 	& 	&KE4*44U44M't^LLGv &W%%%		&
 Lr   c           	         	 ddl m} n# t          $ r g cY S w xY wg }	 |                                }n# t          $ r g cY S w xY w|D ]}	 |                    |          }n# t          $ r Y %w xY wt          |t                    r|                    d          sT|t          d          d         }|	                    |          pi }| 
                    ||dddd          }|                    t          |||                     |S )	zERead already-registered MCP tool schemas without probing MCP servers.r   )registryzmcp-NTFr  )r   r  rR  r  )tools.registryr5  r[   get_all_tool_namesget_toolset_for_toolr=   r   r   ro   
get_schemar?   r   r*  )	r.  r5  r  rv  r  toolsetr/  r  r)  s	            r   _mcp_tools_from_registryr;  0  sx   +++++++   			E++--   			 K K		33I>>GG 	 	 	H	'3'' 	w/A/A&/I/I 	c&kkll+$$Y//52)--k"	<
 <
   	&y&.IIJJJJLs-   	 3 AA
A  
A-,A-c           	         t                      }|                    di           }t          |t                    si }t	                      fd|                                D             }t          |          }d}|st          |          }|rdnd}|                    d            d |	                                D             }t          | |t          |          |d	|d
          S )zCList known MCP tools from already-available runtime inventory only.mcp_serversc                     i | ]Q\  }}t          |          t          t          |          |                    t          |                              RS r   r   r  r?   r   r   scfgr0  s      r   rS  z*_handle_mcp_tools_list.<locals>.<dictcomp>0  Y       D$ 	D		?3t99dGKKD		4J4JKK  r   mcp_runtime_statustool_registryrg	  c                 Z    |                      dd          |                      dd          fS )Nrg  rI   r   r   ri  s    r   r  z(_handle_mcp_tools_list.<locals>.<lambda>0  s'    " 5 5swwvr7J7JK r   r  c                 r    g | ]4}|                     d           |                     d          ,|d         5S )r  rR  r   r   )r   rS  s     r   r{   z*_handle_mcp_tools_list.<locals>.<listcomp>0  sR       #;;y!!*1++h*?*?  r   already_known_runtime_only)r  rc  r4   inventory_scopeunavailable_servers)r[  r?   r=   r>   r  r  r3  r;  r  r,  r(  ro   )r6  r  serversr.  r  r4   rJ  r0  s          @r   r  r  0  s%   
,,CggmR((Ggt$$ )++G   !--//   +74DEEE!F 6()9::$)5v	JJKKJLLL '7'>'>'@'@   WU72    r   c                 p    t          | pd                                                                          dv S )NrI   >   rJ   rM   rL   rK   r   r  s    r   _webui_truthyrM  0  s2    u{!!##))++/IIIr   config_datac                 ^   t          j        dd          }|rt          |          S t          | t                    r| nt                      }t          |t                    sdS t          |                    d          p)|                    d          p|                    d                    S )zReturn whether the third-party notes drawer is explicitly enabled.

    The Memory panel is a primary surface, so this power-user drawer stays
    default-off unless a deployment opts in through config or environment.
    #HERMES_WEBUI_EXTERNAL_NOTES_SOURCESrI   Fwebui_external_notes_sourcesexternal_notes_sourcesnotes_sources_drawer)r]   r^   rM  r=   r>   r[  r?   )rN  	env_valuer  s      r   r
  r
  0  s     	?DDI (Y'''#K66
H++JLLCc4   u.// 	+77+,,	+77)**  r   >   kbr  wikinotesjoplinlogseqnotionllmwikiobsidianreadwise	knowledgellm-wiki>   r  rH
  rV  rW  r  get_notenotebookr^  	read_note
list_notessearch_notesrd  zSearch Joplin notes by keyword.rp  rc  z"List notes from a Joplin notebook.r`  z"Read a specific Joplin note by ID.z!Search Obsidian notes by keyword.rb  z&Read a specific Obsidian note or file.search_pagesz!Search Notion pages or databases.get_pagezRead a specific Notion page.query_knowledge_basez"Query the LLM Wiki knowledge base.	read_pagezRead a specific wiki page.)rX  r\  rZ  r_  r[  c                 >   dddddddd}t          | pd                                                                          }|                    |t          | pd                              d	d
                              dd
                                                    S )NJoplinObsidianNotionzLLM WikiReadwiseLogseq)rX  r\  rZ  r_  r[  r]  rY  rI   r   r3  r#  )r   r   r   r?   r%  r  )r   labelsr  s      r   _note_source_labelrp  	1  s     F $*"oo##%%++--G::gs4:266sC@@HHcRRXXZZ[[[r   r/  	tool_rowsc           	         t          | pd                                          t          fdt          D                       rdS |D ]}d                    t          |                    d          pd          t          |                    d          pd          g                                          t          fdt          D                       r dS dS )	NrI   c              3       K   | ]}|v V  	d S r;   r   r   r   server_ls     r   rx   z+_looks_like_notes_source.<locals>.<genexpr>1  s(      
C
C48
C
C
C
C
C
Cr   Tr3  r   r   c              3       K   | ]}|v V  	d S r;   r   )r   r   haystacks     r   rx   z+_looks_like_notes_source.<locals>.<genexpr> 1  s(      EEDtxEEEEEEr   F)r   r   r   _NOTES_SOURCE_SERVER_HINTSr  r?   _NOTES_SOURCE_TOOL_HINTS)r/  rq  r  rw  ru  s      @@r   _looks_like_notes_sourcerz  1  s    ;$"%%++--H

C
C
C
C(B
C
C
CCC t  88  &B''''-2..
   577 	 EEEE,DEEEEE 	44	5r   c                 Z   t          | pd                                                                          t                                        }|Nt          fddD                       rddddd	dg}n(t          fd
dD                       rddddddg}ng }d |D             S )zBReturn safe expected note-tool hints for configured known sources.rI   Nc              3       K   | ]}|v V  	d S r;   r   rt  s     r   rx   z._configured_note_tool_hints.<locals>.<genexpr>*1  s(      HHDtxHHHHHHr   )rV  r^  rU  r  z(Search this configured knowledge source.rp  r  z3Read an item from this configured knowledge source.c              3       K   | ]}|v V  	d S r;   r   rt  s     r   rx   z._configured_note_tool_hints.<locals>.<genexpr>/1  s(      @@d!@@@@@@r   )r  rW  rd  z$Search this configured notes source.rb  z.Read a note from this configured notes source.c                     g | ]e}t          |t                    t          |                    d           pdd          t          |                    d          pdd          ddfS )r   rI   `   r  r   r  T)r   r   inferred)r=   r>   r  r?   )r   ri  s     r   r{   z/_configured_note_tool_hints.<locals>.<listcomp>61  s        c4  *3776??+@bKKK1#''-2H2H2NBVYZZZ	
 	
  r   )r   r   r   #_NOTES_SOURCE_CONFIGURED_TOOL_HINTSr?   r   )r/  hintsru  s     @r   _configured_note_tool_hintsr  %1  s    ;$"%%++--3355H/33H==E}HHHH,GHHHHH 	!2\]]0effEE @@@@.?@@@@@ 	'8^__$5effEE
 E     r   r.  r  c                 L   i }|pg D ]z}t          |t                    st          |                    d          pd                                          }|sQ|                    |g                               |           {t          | t                    rj|                                 D ]U\  }}t          |pd                                          }|r||v r/t          |g           r|                    |g            Vg }|                                D ]t\  }}t          ||          st          | t                    r|                     |d|i          nd|i}g }	d}
|dd         D ]z}t          |                    d          pdd	          }t          j        d
d|          }|	                    t          |                    d          pdd	          |d           {|	st          |          }	|	rd}
|                    |t          |          t          |                    dd                    t          |                    d                    |                    d          pdt          |	          |
|	d           v|                    d            |S )a  Build a safe notes/knowledge-source inventory from MCP servers/tools.

    Some WebUI deployments can read ``mcp_servers`` from config before their
    local runtime/tool registry has hydrated MCP tool metadata.  Still show
    configured note/knowledge servers (for example Joplin) in that case so the
    drawer reflects connection/configuration state instead of appearing empty.
    rg  rI   r   r0  Nr  r   r  r  z6(?i)\b(api[_-]?key|token|password|secret)\s*[:=]\s*\S+z
[REDACTED]r  rp  configured_hintr  TrR  r  r  )r   r  r  rR  r  r  tool_sourcer  c                 Z    |                      d           |                      dd          fS )NrR  r  rI   r   rF  s    r   r  z3_notes_sources_from_mcp_inventory.<locals>.<lambda>v1  s(    cggh&7&7"7"9M9M!N r   r  )r=   r>   r   r?   r   rm  r   r  rz  r  r  r  r  rp  r  ro   r  )r.  r  	by_serverr  rg  rS  r/  sourcesrq  
safe_toolsr  r?  s               r   !_notes_sources_from_mcp_inventoryr  A1  s    (*I 6 6$%% 	TXXh''-2..4466 	VR((//5555"D)) 6/5577 	6 	6OFGfl++1133K +":":'R88 6$$["555G&__..  	'	:: 	DNO_aeDfDf|"&&v/?@@@msu{l|
bqbM 	 	D)$((=*A*A*GRsSSSD6SUacghhD.txx/?/?/E2RPPP#       	04V<<J 0/'//GKK	488997;;x0011kk(++8yj//&	
 	
 		 		 		 		 LLNNLOOONr   c                    t                      }t          |          st          | dg ddddg d          S |                    di           }t	          |t
                    si }t                      fd|                                D             }t          |          }d}|st          |          }|rd	nd
}t          | dt          ||          |dddt          d          d          S )z;List note/knowledge MCP sources for the WebUI Notes drawer.Fr   disabled_by_defaultT)r  r  r4   rI  attach_supportedautomatic_recall_unchangedrecent_ai_notesr=  c                     i | ]Q\  }}t          |          t          t          |          |                    t          |                              RS r   r?  r@  s      r   rS  z._handle_notes_sources_list.<locals>.<dictcomp>1  rB  r   rC  rD  rg	  rH  r  r  )r[  r
  r(  r?   r=   r>   r  r  r3  r;  r  _joplin_recent_ai_notes)r6  r  rK  r.  r  r4   r0  s         @r   r  r  z1  s;   
,,C*3// 	 4 %*.!
 
   	 ggmR((Ggt$$ )++G   !--//   +74DEEE!F 6()9::$)5vW45EuMM7!&*2;;;    r   r4   c                    t                      }t          |t                    r|                    di           ni }t          |t                    si S t	          | pd                                                                          }|                                D ]W\  }}t	          |pd                                                                          |k    rt          |t                    r|c S Xi S )Nr=  rI   )r[  r=   r>   r?   r   r   r   r  )r4   r  rK  source_lr   
server_cfgs         r   _notes_configured_serverr  1  s    
,,C,6sD,A,AIcggmR(((rGgt$$ 	6<R  &&((..00H#MMOO  jtzr??  ""((**h66:jRV;W;W6Ir   c                     t          d          } t          | t                    r|                     di           ni }t          |t                    si }t	          |                    d          p t
          j                            d          pd                              d          }t	          |                    d          p t
          j                            d          pd          }||fS )NrX  r  
JOPLIN_URLzhttp://127.0.0.1:41184r   JOPLIN_TOKENrI   )r  r=   r>   r?   r   r]   r  rc  )r  r  r  r  s       r   _joplin_connection_from_configr  1  s    
"8
,
,C *3 5 5
=#''%


2Cc4   
cggl##_rz~~l'C'C_G_
`
`
g
ghk
l
lC''O2:>>.+I+IORPPE:r   paramsc                    ddl m} ddlm}m} ddlm}m} t                      \  }}|st          d          dt          | pd                              d          z   }	t          |pi           }
| |	 d ||
           } ||d	d
| i          }	  ||d          5 }|                    d                              dd          }ddd           n# 1 swxY w Y   n=# |$ r}t          d|j                   dd}~w|$ r}t          d          dd}~ww xY w	 t!          j        |          }n# t$          $ r t          d          dw xY wt'          |t                    r|ni S )zBCall the local Joplin Web Clipper API without logging credentials.r   )	urlencode)r
  r
  )	HTTPErrorURLErrorzJoplin token is not configuredr   rI   r}  r	  ztoken r	  r  r  i r   r%  r  NzJoplin API returned HTTP zJoplin API is not reachablez Joplin API returned invalid JSON)r  r  r
  r
  r
  urllib.errorr  r  r  rh   r   rd  r>   r  r  r\  r  r  r[   r=   )r    r  r  r
  r
  r  r  r,  r  	safe_pathrN   r  r
  rg  rQ   r  r  s                    r   _joplin_api_getr  1  sI   &&&&&&////////00000000466OHe ;9:::c$*"oo,,S111I2E
5y
5
599U#3#3
5
5CgcO5Ee5E5E#FGGGGBWWa((( 	MH--	**11')1LLC	M 	M 	M 	M 	M 	M 	M 	M 	M 	M 	M 	M 	M 	M 	M K K K?SX??@@dJ B B B677TABGz# G G G;<<$FGdD))144r1sT   C& #+CC& CC& !C"C& &D +DD DD $D9 9ErI      rN   c                   t          j        ddt          | pd                                                    }|sdS t          |pd                                                                          }|rK|                                                    |          }|dk    rd|t          d|dz
            d          z   }t          |          |k    r|d |                                         dz   S |S )Nr  r3  rI   r  r  r   r(   )	r  r  r   r   r   rZ  r  ro   rc  )r   rN   r`  r.  r\  r^  s         r   _note_snippetr  1  s    6&#s4:2//5577D rEKR  &&((A 3jjll""884AsRx 0 0 1 122D
4yy5FUF|""$$u,,Kr   c                ^   t          | pd                                          } | sg S t          dt          t	          |pd          d                    }t          d| dd|d          }t          |t                    r|                    d	          ng }g }t          |t                    r|ng D ]}t          |t                    st          |                    d
          pdd          }|sAt          |                    d          pdd          }t          |                    d          pd          }|                    ||t          t          ||           d          t          |                    d          pdd          |                    d          dd           |S )NrI   r   r   ry  z/searchr  z$id,title,body,parent_id,updated_time)rN   r  fieldsr`  r  r|  r-   r  r  r  r  r   i  	parent_idupdated_timerX  )r|  r  rJ
  r  r  r4   )r   r   r  r[  r  r  r=   r>   r?   ra  r  r   r  )	rN   r`  r  r	  rJ  ri  note_idr  r   s	            r   _joplin_search_notesr  1  s   ""$$E 	3s5;B'',,--E98	' '  D !+4 6 6>488GBDG!$--5tt2  #t$$ 	()<"BGGG 	&swww'7'7'E:SQQQ3776??(b))-mD%.H.HPSTTT/0D0D0JRTUUUGGN33
 
 	 	 	 	 Nr   r  c                     t          | pd                                          } t          j        d|           st	          d          t          d|  ddi          }|                    d          st	          d          t          |                    d	          pd          }t          |          d
k    r|d d
                                         dz   }t          |                    d          pdd          t          |                    d          pdd          t          |          t          |                    d          pdd          |                    d          |                    d          ddS )NrI   z[A-Za-z0-9]{16,64}zInvalid Joplin note id/notes/r  z1id,title,body,parent_id,updated_time,created_timer|  zJoplin note not foundr   rx  z*

[Preview truncated at 50,000 characters]r-   r  r  r  r  r  r  created_timerX  )r|  r  r   r  r  r  r4   )r   r   r  rC
  rh   r  r?   ro   rc  r  r-  )r  r  r   s      r   _joplin_get_noter  1  su   '-R  &&((G<-w77 31222.W..E1  D 88D>> 20111txx%2&&D
4yy6GVG}##%%(VV$TXXd^^%9rDDD'(9(9(GZsSSST""+DHH[,A,A,GRrRRR0000  r   ))CURRENT_CONTEXT_IDzCurrent Context)OPEN_ISSUES_IDzOpen Issues)AGENT_MEMORY_IDzAgent Memory)CONVENTIONS_IDzConventions / Preferences)INFRA_IDInfrastructure)SERVICES_IDServicesc                      t                      } t          | t                    r|                     d          nd }|sd S 	 t	          t          |                                                    S # t          $ r Y d S w xY w)Nprefill_messages_script)r[  r=   r>   r?   r   r   r`   r[   )r  
path_values     r   _joplin_prefill_script_pathr  2  s    
,,C7A#t7L7LV2333RVJ tC
OO$$//111   tts    -A. .
A<;A<script_pathc           	         | pt                      } | r(|                                 r|                                 sg S 	 |                     dd          }n# t          $ r g cY S w xY wd t          j        d|          D             }g }t                      }t          D ]Q\  }}|	                    |          }|r||v r!|
                    |           |                    |||ddd           R|S )	a  Find stable Joplin note IDs referenced by the configured recall script.

    This keeps the WebUI generic: it does not hard-code a user's note IDs, but
    can still surface the notes that the configured AI prefill/recall script is
    known to read for automatic context.
    r   r%  r  c                 `    i | ]+}|                     d           |                     d          ,S )r   r  )r  )r   r  s     r   rS  z,_joplin_recall_note_refs.<locals>.<dictcomp>82  s>        	AA  r   z<(?m)^\s*([A-Z0-9_]+_ID)\s*=\s*["\']([A-Fa-f0-9]{16,64})["\']
ai_prefillautomatic_recall)r|  r  constantused_byused_reason)r  rz   r   r   r[   r  finditerr   _JOPLIN_AI_RECALL_NOTE_PRIORITYr?   r   r   )r  r.  	constantsr  r  
const_namer  r  s           r   _joplin_recall_note_refsr  *2  sL    >!<!>!>K k0022 +:M:M:O:O 	$$gi$HH   			 [!`bfgg  I D55D<  
E--
++ 	'T//"#-
 
 	 	 	 	 Ks   A A%$A%r  c                    	 t          dt          t          | pd          d                    } n# t          $ r d} Y nw xY wg }t	                      d|          D ]s}	 t          d|d          ddi          }n# t          $ r Y ,w xY wt          |                    d          p|                    d          pd	d
          }|sn|                    |t          |                    d          p|                    d          pdd          t          |                    d          pd	d          t          |                    d          pd	d
          |                    d          p|                    d          |                    d          d|                    d          pd|                    d          pdd	           u|S )zJReturn safe Joplin notes that the configured AI recall path recently uses.r   r  r   Nr  r|  r  z>id,title,parent_id,updated_time,user_updated_time,created_timerI   r-   r  r  r  r  r  r  r  user_updated_timer  r  rX  r  r  r  r  )	r|  r  r  r  r  r  r4   r  r  )	r  r[  r  r[   r  r  r  r?   r   )r`  rW  r  r  r  s        r   r  r  M2  s   As3uz??B//00   E'))&5&1  	"#8SY#8#8Z;  DD  	 	 	H	($)N3774==)NBVXYYY 	+DHHW,=,=,_AQAQ,_U_gjkkk+CGGG,<,<,B#NNN/0E0E0KSUVVV HH%899UTXXn=U=U HH^44wwy))9\77=11G5G

 

 
	 
	 
	 
	 Ls   -0 ??A::
BBc           
         t                      st          | dg ddd          S t          |j        pd          }t	          |                    ddg          d	         pd                                                                          }t	          |                    d
dg          d	         pd                                          }	 t          |                    ddg          d	         pd          }n# t          $ r d}Y nw xY w|dk    rt          | |g ddd          S 	 t          | d|t          ||          d          S # t          $ r.}t          | d|g t	          |          dd          cY d }~S d }~ww xY w)Nr   $External notes sources are disabled.)r4   rJ  r   r4  r5  rI   r4   rX  r   r\  r`  20r   z8Search is currently implemented for Joplin sources only.r  r  )r4   rN   rJ  )r4   rN   rJ  r     )r
  r(  r   rN   r   r?   r   r   r  r[   r  rh   )r6  r7  rN   r4   r\  r`  r  s          r   r  r  l2  s   *,, ~ZBIoppy|}}}}V\'R((E8hZ003?x@@FFHHNNPPFEIIcB4  #)r**0022AEIIgv..q17R88   VE  A  A  JM  N  N  N  	NjXFZ[\diFjFjFjkklll j j jXbSVWZS[S[\\ehiiiiiiiiijs0   
,C7 7DD&"E	 	
F#E<6F<Fc                 z   t                      st          | dddd          S t          |j        pd          }t	          |                    ddg          d	         pd                                                                          }t	          |                    d
dg          d	         pd                                          }|dk    rt          | |ddd          S 	 t          | dt          |          d          S # t          $ r,}t          | dt	          |          dd          cY d }~S d }~ww xY w)Nr   r  )r4   r   r4  r5  rI   r4   rX  r   r|  z9Preview is currently implemented for Joplin sources only.r  )r4   r  r  )
r
  r(  r   rN   r   r?   r   r   r  rh   )r6  r7  rN   r4   r  r  s         r   r  r  ~2  s\   *,, oZ:`aajmnnnnV\'R((E8hZ003?x@@FFHHNNPPF%))D2$''*0b117799GV6qrr{~OX7G7P7PQQRRR O O OXCAA#NNNNNNNNNOs   $D 
D:!D5/D:5D:c                     t                      }|                    di           }t          |t                    si }t	                      fd|                                D             }t          | |ddd          S )zDList configured MCP servers with safe, read-only runtime visibility.r=  c                 x    g | ]6\  }}t          ||                    t          |                              7S r   )r  r?   r   r@  s      r   r{   z,_handle_mcp_servers_list.<locals>.<listcomp>2  sK       D$ 	dGKKD		$:$:;;  r   T)rK  toggle_supportedreload_required)r[  r?   r=   r>   r  r  r(  )r6  r  rK  r   r0  s       @r   r  r  2  s    
,,CggmR((Ggt$$ )++G   !--//  F W     r   c                 z   ddl m}  ||          }|st          | d          S t                      }|                    di           }t          |t                    si }||vrt          | d| dd          S ||= ||d<   t          t                      |           t                       t          | d|d	          S )
zDelete an MCP server by name.r   unquoter  r=  MCP server 'r  r4  T)r  deleted)r  r  r&  r[  r?   r=   r>   r"  r   r#  r(  )r6  r   r  r  rK  s        r   r  r  2  s    $$$$$$74==D 07.///
,,CggmR((Ggt$$ 77<4<<<cBBB C+--s333OOOWTd33444r   c                 >   ddl m}  ||          }|st          | d          S d|vrt          | d          S t          |d                   }t	                      }|                    di           }t          |t                    si }||vrt          | d| dd	          S t          ||         t                    st          | d| d
d          S |||         d<   ||d<   t          t                      |           t                       t          | d||d          S )zGToggle enabled state for an MCP server (PATCH /api/mcp/servers/{name}).r   r  r  r  zenabled field is requiredr=  r  r  r4  z' has invalid configr  Tr  )r  r  r&  r  r[  r?   r=   r>   r"  r   r#  r(  )r6  r   r   r  r  r  rK  s          r   r  r  2  sJ   $$$$$$74==D 07.///778884	?##G
,,CggmR((Ggt$$ 77<4<<<cBBBgdmT** L7E4EEEsKKK&GDM) C+--s333OOOWT4GDDEEEr   r  c                    t          | t                    rt          |t                    s| S i }|                                 D ]\  }}t          |t                    r7|t          k    r,||v r't          ||         t                    r||         ||<   PQt          |t                    r9||v r5t          ||         t                    rt          |||                   ||<   |||<   |S )zHRemove masked placeholder values from submitted dict, keeping originals.)r=   r>   r  r   _MASKED_PLACEHOLDER_strip_masked_values)r  r  rO
  rN  r  s        r   r  r  2  s    i&& j4.H.H G!!  1a 	!':":":H}}HQK!=!=}%a[
4   	Q(]]z(1+t7T7T]-a!==GAJJGAJJNr   c                    ddl m}  ||          }|st          | d          S i }t                      }|                    di           }t          |t                    si }|                    |i           }|                    d          r`|d                                         |d<   |                    d          r-t          |d         |                    di                     |d<   n|                    d          r|d                                         |d<   |                    d          r/t          |d         t                    r|d         n|d         g|d<   |                    d	          r-t          |d	         |                    d	i                     |d	<   nt          | d
          S |                    d          1	 t          |d                   |d<   n# t          t          f$ r Y nw xY w|||<   ||d<   t          t                      |           t                       t!          | dt#          ||          d          S )zAdd or update an MCP server.r   r  r  r=  r  r  r  r  r  zurl or command is requiredr  NT)r  rg  )r  r  r&  r[  r?   r=   r>   r   r  ra  r  rh   r  r"  r   r#  r(  r  )r6  r   r   r  r  r  rK  existing_cfgs           r   r  r  2  s\   $$$$$$74==D 07.///J
,,CggmR((Ggt$$ ;;tR((Lxx : K--//
588I 	k$8i,JZJZ[dfhJiJi$j$jJy!	)		 : $Y 5 5 7 7
988F 	d1;DL$1O1O!cfVZ[aVbUcJv88E?? 	_ 4T%[,BRBRSXZ\B]B] ^ ^Ju78999xx	&	$'Y$8$8Jy!!I& 	 	 	D	GDM C+--s333OOOWT_T:-N-NOOPPPs   G$ $G87G8r;   r   )rF   N)r  )rm  )r  )r   )F)r  )r  r  )rI   (D  __doc__r  r  r@  r  r  r  loggingr]   r  r  r6  r  r  r  r  r  rK  rp  pathlibr   
contextlibr   r  r   r   api.agent_sessionsr   r	   r
   r   api.compression_anchorr   api.session_eventsr   r   r   	getLoggerr  r   r	  r	  r	  TimeoutErrorrg   r  r   r>   r   r  __annotations__LockrJ  r   r  r  _CRON_OUTPUT_CONTENT_LIMITrb  r(  r#   objectr>  r  r  r'   ra  r  r  r  r  r  r+   r  r  r  r  r  rD   rZ   rE   r  rR   ra   ri   rr   r   r   r   r   tupler   r   r   r  r  r   r  r&  r)  r/  r3  rG  rM  rQ  rU  r  r_  rh  rn  rr  r   rw  ry  r  r  r  r  r  r  r
  r  r  RLockr  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  r  r  r  r  r  r  r  r   r!  r"  r#  r$  rR  r%  r&  r'  r(  rT  r)  r*  r+  r,  r-  api.agent_healthr.  api.request_diagnosticsr/  api.system_healthr0  r8  rP  r[  rd  rj  r  rt  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,  r3  rF  rJ  rP  rT  rW  rl  rp  rr  ru  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rG  r_  r   r  r  r  r  r  r  r  r  r  rt  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.  rI  api.run_journalr/  r0  r1  api.providersr2  r3  r4  r5  r6  api.onboardingr7  r8  r9  r:  r  r;  r<  r=  r%  r>  _submit_pending_rawr?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rt
  rY  r  r]  ra  rj  rl  r	  r	  rt  r	  ru  rv  rw  r	  rx  r	  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r3  r  r  r  r  r  r  r  re  rl  rw  r  r  r  r  r  r  r  r  r  r  r  r[   r  r  r  rI  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  rD	  rL	  r`	  r  re	  ri	  r  r	  r	  r	  r	  r  r  r  r  r  r  r  r  r  r  r  r  rD
  rK
  r  r  r  r  r  r&  r'  r
  r
  r
  r
  r
  r
  r
  r
  r
  r(  r)  r  r  r*  r0  r  r1  r2  r3  r4  r5  rD  rH  rJ  rL  rR  r  r  r  r  rc  r6  r7  r8  rq  r9  r:  r;  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  r  rL  r  rM  r  r  r  r   r!  r  r"  r#  rP  rR  rU  rW  rY  r]  ra  r$  rN  rO  r  r  rP  rQ  r  r  r  r  r  r\  r[  r[  r  r  r  r  r  r  r!  r&  r*  r3  r;  r  rM  r
  rx  ry  r  rp  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   <module>r     se5    
      				    				  				        



       				             + + + + + + + +            ? > > > > >          
	8	$	$   (* De$ ) ) )#Y^%% ,. $sDy/ . . . .	 0 0 &- #! ! LL:KLLL 8 8 !4V#4   
 $29>#3#3   /1AB &W&|44 13 S$u+-. 3 3 3,in.. (* %  & (w(88 35 $sDK/0 5 5 5 .	 0 0 *, '! '     , , , ,. ) ( ( ( ( (-D - - - -hD h h h h, $ 4    
 
4: 
#PT* 
 
 
 
+$ +4: + + + +4    $3 4    S Sd ScDj SD S S S Sl.c .T
 .uTD[RVY]R]E]?^ . . . .b3S 3d 3uTD[$QU+=U7V 3 3 3 3
3 D T    !td{ !t ! ! ! !HTD[ D T    @6c 6d 6 6 6 6L #$ 1s 1 1 1 1Md M M M M  6 6 6,DdO , , , ,^1s 1 1 1 1
-C - - - -
%S %U4;%7 % % % %	1c 	1c 	1 	1 	1 	1 9S  c # WZ    04 D    "<T
 < < < <s3x    C$J    ,D , , , ,*\ \ \,  "B  B  B JQ6 Q6 Q6 Q6h 	   !,, *G3    @B DsCx%t*<<= B B B))/++ 
s 
 
 
 
?S ?U38_ ? ? ? ?
&sCx 
&TD[ 
& 
& 
& 
&MsCx M4 MD M M M M
# # # #) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )T                        8 7 7 7 7 7 6 6 6 6 6 6 9 9 9 9 9 9
c 
d 
 
 
 
H$ H H H HV BG    $ 4     c    *D    4     c3:o(>    * #* CRVJ [_    "S    0Q4 Q Q Q QC D     3 c d       +c + + + +2?D 2? 2? 2? 2?j#     >B   edl d     @D         c D    4 4 4$%4 % % % %s sTz    <cDj < < < <!D4K !D ! ! ! !Hb4 b b b b8	KD 	KT 	K 	K 	K 	K#*     .5t 5c#hC6H0I 5 5 5 5


 #h
 !X	

 

 
 
 
 
   R RS RT R R R Rt d
    3 5cDj3I     3 Y] bf    4 "&A, A,DjA,$JA, 3d
D !A, A, A, A,H$d
 $uS$Y?O $ $ $ $#    .-S - - - -cDj      0 0:0Dj0 	0 0 0 0l $(! !:!d
! Dj! 3:sTz!"	! ! ! !0: : : : : :	S 	T 	 	 	 	# #3 #3 # # # #L	,4 	,C 	, 	, 	, 	,T d    S    && #C&  H& 
	& & & &R+T + + + +"    $# c VZ    ") ) ) ) ) eTXZ]T]N^    B     :
P$ 
P 
P 
P 
P1 1 1cDj 1D 1 1 1 1h"d " " " "JK# K$ K K K K	T 	e 	 	 	 	$ 4    (   CZ  tDz C ^bcg^h    ;D ;D ;T ; ; ; ;|54 5C$J 5 5 5 5 .3- - -4j- '+- 
$Z	- - - -`                                           ,                                 O N N N N N N N N N                    
 ~ } } } } } } } } } } } } }                                                      ..**O,,33&&K00..//33HINE#%%OOO" ;= 4T%+%6 67 < < <     @# @%+ @$ @ @ @ @C td{ 3 SW    4
=S 
=t 
=C 
=D 
= 
= 
= 
=> >t > > > > >@2                  2 2 211.. ''O112 5!(*  >%-3  &A(5/  A!02  1 C=/m Z  F%01  F%01  :!+,  1^7/T1  5+.  %r1#h2  !@#0D Op pfd
 s    @& V   
 )((   Cc C C C C5>T 5> 5> 5> 5>r w H Yd Y Y Y Y #*    &
%D 
%c 
%cDj 
% 
% 
% 
%	sTz 	 	 	 	  %I & &1g& & &   
JdCo 6 J J J J54< C$J         2D T$Z    4>
 >
 >
 >
 >
B    
i i i i i^D     % $    (&T & & & &Rt    BN NdTk NU4:=N N N N Nb  B  "c":;;       36 
 
 
# 
 
 
 
@ @ @ @ @ @F
 
 
 
 
"  	9 	 	 	 	 	    : : : : :,c4 c c c cR%BD B B B BJ6T    $d    $4     
"  fee     t   #Y^%% G G GT  ,     D'P 'P 'PT!5 !5 !5H   T cDj    C C$J 4    68 8 8v	 	 	5 5 585 5 5"5 5 5$) ) )     F  85 5 5p  4C 3 3    .c c eCHoPT>T    : tx 8 8 8t 83 8S 8Y\ 8filpfp 8 8 8 8v u          $ S RU    6nc nc ncb3 S TD[    :$s $ $ $ $s    )$T )$4 )$),)$9<)$ )$ )$ )$XQ Q Qh#V #V #VL5 5 5$= = =&9* 9* 9*xD D D() ) )E( E( E(PD D D(V< V< V<r0Z 0Z 0Zf9 9 9B6c 6d 6 6 6 6r% %s %3 % % % % %(> > >*
0 
0 
0$? $? $?N) ) )^8 8 8 8.5} 5} 5}pXa Xa Xav C  Z_bfZf  ko        2D D D D DQ Q3 Q# Qs Q Q Q Q   $' ' ' 
'
 ' ' ' ' ' ' 'T4      "	j j j 
j
 j j j j j j jZ	M 	M 	M  .	C 	C 	 	 	 	G G GTw w w wvS    $  <o o od9 9 9<0 0 0C C C0
> 
> 
> K  K  KF	. 	. 	.	. 	. 	.c    # # # # #,C , , , ,
T 
 
 
 
4    <
$ 
$ 
$
$ 
$ 
$$ $ $" 3    -$s) - - - -$ $ $$$ $ $$$ $ $8[? [?3 [?S [?SV [? [? [? [?|5 5 5<5 5 5>$ $ $"$ $ $$$S $ $ $ $,$ $ $D$$ $$ $$N0 0 000 0 0.0 0 0,0 0 040 0 0*0 0 0D0 0 0:Q0 Q0 Q0h$7 $7 $7N7 7 77 7 7 = = =8ZL# ZLC ZL ZL ZL ZL ZL ZLz4 4 4& #       :  :  :F. . . . . . . .(4 4 4 4  62 2 2j7f 7f 7ft# # #&_I _I _ID	# # #T  	 4Z $J	
  
   :d td{    <4  $     & $QU+ Z^    ,#      (?c ?D ?T ? ? ? ?DS S# S ScDj SRUX\R\ Shl Sy} S S S Sj j jZQ Q Q8: : :&PDI P P P Pc D T#Y    3F 3F 3FlM M M66 f     F t    & V     d W[    , t X\    $n n nbW W W@ [ Z Z Z Z Z Z Z Z Z Z Z       "T#t)_    *0 0 0 0fC C        " 13      #  tDz        F	 	 	  .  ,  <  <JD J J J J      &        0QRR.RSS,PQQ  0STT-UVV
  0STT,JKK
 (8\]]-IJJ
 (8\]]-IJJ%' ' #2\S \S \ \ \ \# $t*     S T$Z    86 6T$Z 6TXY]T^ 6 6 6 6r" " "J	S 	T 	 	 	 	c3h    2 2# 2td{ 2d 2 2 2 26c    C  c     68    s DJ    @c d    .# # # TD[       $+  d        F -.   c $t*    >j j j$O O O  $5 5 5&F F F0 +   ""Q "Q "Q "Q "Qs%   69_0 0A`>=`>)c c#"c#