
    }-j                       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mZ ddlmZ ddlmZ ddlmZmZmZmZ ddlmZ  ej        e           Z!e"e#e$e%e&fZ'i Z(e)e*e+f         e,d<    ej-                    Z.i Z/e)e*e)f         e,d	<    ej-                    Z0d
Z1dZ2dZ3d eD             Z4ddi dZ5e)e*e6f         e,d<    ej-                    Z7ddhZ8 ej        d          Z9i Z:e)e*e;e+         f         e,d<    ej-                    Z<dZ=dZ>dZ?ddl@mAZA deBfdZCdefdZDdededeBfdZEdede;e         de*dz  fd ZFd!ede;e         fd"ZGde)fd#ZHd$e*de)fd%ZIdd!ed&e*dz  de)fd'ZJd(e*d!edeKedz  edz  f         fd)ZLd(e*d!ede)fd*ZMd(e*de)fd+ZNd,ZOde*fd-ZPdeBfd.ZQd/ ZRd0 ZSde)e*e)f         fd1ZTd2e*fd3ZUd2e*fd4ZVd2e*deKeBe+f         fd5ZWd6e*deXfd7ZYe2fd6e*d8eXde*fd9ZZd:e)de)fd;Z[de;e)         fd<Z\de]e*         fd=Z^de*dz  fd>Z_d:e)fd?Z`d@ ZadA ZbdB ZcddCZddDdEdFdEdGZedHdIdJdKdLdMdNdOZfdPZgi Zhe)eKe*e*f         eKe+e)f         f         e,dQ<    eji                    Zjde*fdRZkdSe*deKe*e*f         fdTZldUeKe*e*f         de)dz  fdVZmdUeKe*e*f         dWe)ddfdXZnddYZoddZlpmqZqmrZrmsZsmtZtmuZumvZvmwZwmxZxmyZymzZzm{Z{m|Z|m}Z}m~Z~mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ dd[lmZmZmZmZmZmZmZmZmZmZ dd\lmZ dd]lmZ dd^lmZ d_e*deBfd`ZdeBfdaZdeBfdbZddl	Zdce*deKe*e*dz  f         fddZdee*dfe*dz  dge*dz  deBfdhZde]e*         fdiZdeBfdjZde*fdkZddldme+dz  deBfdnZddpeXdeBfdqZdr ZdeBfdsZdce*dz  de*fdtZdue)deKe]e*         e]e*         f         fdvZdwe*dxe*dye]e*         dze]e*         deBf
d{Zd|e*d}e*deBfd~Zde*d|e*deBfdZdce*dz  de*dz  fdZd|e*deKe*e*dz  f         fdZd|e*de*due)deBfdZ	 dde*dz  de*dz  deKe*e*dz  eBf         fdZde*dz  deKe*eBf         fdZde*fdZde*fdZde*dz  fdZ	 dd|e*dz  de*dz  de*dz  deKe*dz  e*dz  f         fdZde*de)fdZde*de)fdZdeBfdZde)de*de*fdZde)de*fdZde)deBfdZdeXfdZde)de]e*         de]e*         deBfdZdeBfdZd$e*deBfdZde)de+fdZde)deBfdZdZefde;e)         deXde;e)         fdZde)de)de)fdZde)de*dz  fdZde;e)         de;e)         fdZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZ ddlmZmZmZmZ ddlmZmZmZmZ ddlmZmZmZm Z  ddl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 nN# e$ rE d Zd Zd Z	d Z
d Zd Zd Zd Zd Zi Z ej-                    Z e]            ZY nw xY wi Ze)e*e;ej                 f         e,d<   de*dej        fdZde*dej        ddfdZde*de)dz  deXddfdZde*de)dz  deXddfdZde*de)ddfdÄZ	 ddĐlmZmZmZmZ m!Z" n# e$ r dń ZdƄ ZdZ dǄ ZY nw xY wddddddddΜddddddddΜddddddddΜddddddddΜddddddddΜddddddddΜddddddddΜddddddddΜddddddddΜdddd dِdddΜddddddddΜd	Z#d
e*dz  de*fdZ$dZ%ddddZ&h dZ'dZ(dZ)deXfdZ*deBfdZ+dZ,dZ-defdZ.dede*dz  fdZ/de)de*de*dz  fdZ0de*dz  fdZ1dZ2 e3d d D                       Z4deKee*eBf         fd!Z5d"e+dz  de*dz  fd#Z6d$edeXfd%Z7d&ede;e         fd'Z8de)fd(Z9deBfd)Z:deBfd*Z;de)fd+Z<dېd-e+de)fd.Z=de)fd/Z>dאd0e)dz  deKe)eBf         fd1Z?d2 Z@d3ZA e]eA          ZBd4 ZCd5d6de*fd7ZDdde)fd8ZEdeBfd9ZFd:ZGd;eHdeBfd<ZIdeBfd=ZJdeBfd>ZKdeBfd?ZLdeBfd@ZMdAdBdCdDdEdFdFdGdHdIdJdKdLZNh dMZOdN ZPdO ZQdP ZRdQ ZSdR ZTdS ZUdT ZVdU ZWdV ZXdW ZYdX ZZdY Z[dZ Z\d[e*d\e*de*fd]Z]d^e*d_eXdeKeXeXf         dz  fd`Z^ddadbedce*d[e*dde*dee*dz  f
dfZ_dg Z`dh Zadi Zbdj Zcdk Zddl Zedm Zfdn Zgdo Zhdp Zidq Zjdr Zkdd6e*d8eXde*fdsZldt Zmdu Zndv Zodw ZpdݐdyZqdz Zrd{ Zsd|e*d}e+dz  ddfd~Ztddd|e*de*d|e*de*d}e+dz  f
dZudddxddxdd|e*de*d|e*deBdeBf
dZvd ZwdאdZxde*fdZyd Zz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 Zd Zd Zd Zd Zd Z G d d          ZdאdZd Zd Zd Zd Zd Zd Z	 	 dd$e*de*de*dz  deXdz  deBde)fdZde)de)dz  fdZde)dbe)deBfdZde6de)dz  deBfdZd$e*de)deBfdZd$e*de)deBfdZdd$e*de*de*dz  deXdz  deBde)fdZd Zd Zd Zd Zde6de6fdZde6deBfdZde6de6fdZde;de;deBfdZde;de;deBfdZd ZdÄ ZddlpmZmZmZmZ dń ZdeBfdƄZde)e*e)f         fdǄZdאdȄZd8eXde*fdɄZde*fdʄZdːd6d8eXde;e)         fd̄Zd̈́ Zd΄ Zdτ ZdЄ Zdф Zd҄ Zdӄ ZdԐZdՄ Zdք Zd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)MESSAGING_SOURCESis_cli_session_rowis_cli_session_row_visibleread_session_lineage_report)visible_messages_for_anchor_RUNNING_CRON_JOBS_MANUAL_COMPRESSION_JOBSX  i@     c                 t    h | ]5}t          |                                                                          6S  strstriplower.0ss      /root/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   )_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   querygetr   r   )
parsed_urlqsraws      r   _all_profiles_query_flagr4   ^   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.profilesr7   r   	Exceptiontools.skills_toolr9   osgetenvr   home
expanduser)r7   r9   s     r   _active_skills_dirrC   i   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)rD   rE   s     r   _skill_path_withinrK      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   )rH   rJ   partslen)rL   rM   
skills_dirrel_pathrP   s        r   _skill_category_from_pathrT      sz    !  
	++J77HH 	 	 	H	u::??8OOOtt4s   
))rR   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 Nr   r   ps     r   	<genexpr>z,_active_skill_search_dirs.<locals>.<genexpr>   s(      @@DGG@@@@@@r   c                 :    g | ]}|                                 |S r   )existsrY   s     r   
<listcomp>z-_active_skill_search_dirs.<locals>.<listcomp>   s%    ***!qxxzz*A***r   )agent.skill_utilsrV   extendr=   )rR   dirsrV   s      r   _active_skill_search_dirsrb      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_retainedrd   worktree_branchworktree_repo_root)getattr)sessionrd   payloadrf   rg   s        r   _worktree_retained_payloadrk      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)rk   get_sessionKeyErrorr=   loggerdebug)rl   s    r   )_worktree_retained_payload_for_session_idrt      sw    )+c*N*N*NOOO   			   NPSTTT			s     A&AAcategoryc           
      z   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 s||
v r|                    dd          }|sY|                                                    d          D ]1}|                                }|r|                    d          s|} n2t-          |          |k    r|d|dz
           dz   }|	                    |           |                    ||t3          ||          d           b# 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 /)successr8   
categoriesmessageSKILL.mdc              3       K   | ]}|v V  	d S rX   r   r   partrz   s     r   r[   z(_skills_list_from_dir.<locals>.<genexpr>   s)      KKD4//KKKKKKr   utf-8encodingN  name@   descriptionr*   
#rO   ...)r   r   ru   z Failed to read skill file %s: %sz)Skipping skill at %s: failed to parse: %sexc_infoc                 F    g | ]}|                     d           k    |S ru   r0   )r   r   ru   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 )ru   Nr   r   s     r   r[   z(_skills_list_from_dir.<locals>.<genexpr>  s?      WW!QUU:EVEVWAEE*--WWWWWWr   )r   r8   r   countz@Use skill_view(name) to see full content, tags, and linked fileshintz%No skills found in skills/ directory.r   ) r_   rx   r>   ry   rz   r{   r|   r}   r~   r]   mkdirsetrb   anyrP   parent	read_textr0   r   r   split
startswithrQ   addappendrT   UnicodeDecodeErrorPermissionErrorrr   rs   r=   sorted)rR   ru   rx   ry   r{   r|   r}   r~   
all_skills
seen_namesdisabledsearch_dirsscan_dirrL   	skill_dircontentfrontmatterbodyr   r   lineer   resultrz   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:%%)9)9)oomR@@" " $

 2 24 8 8 " "#zz|| "(<(< "*.K!E{##&<<<"-.J0F0J.J"Ke"SKt$$$!! $'2$=h$T$T     '8 N N N?1MMMMMMMM   ?1W[         ?"	H  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          }|r|                                sdS |g}d|v r7|                    dd          \  }}|r|r|	                    | d|            |D ]}||z  }	t          ||	          s|	                                r |	d	z                                  r	|	|	d	z  fc S |	                    d
          }
|
                                rt          ||
          r|
j        |
fc S  ||d	          D ]}t          fd|j        D                       r#|j        }|j        |k    r||fc S 	  ||                    d          dd                   \  }}|                    d          |k    r||fc S # t&          $ r Y w xY w|                    d          D ]4}
|
j        d	k    r|
j        |k    rt          ||
          r|
j        |
fc S 5dS )z?Resolve a WebUI skill name inside an explicit skills directory.r   rw   )rz   r|   r*   r   NN:   r   z.mdc              3       K   | ]}|v V  	d S rX   r   r   s     r   r[   z%_find_skill_in_dir.<locals>.<genexpr>*  s)      GGt++GGGGGGr   r   r   Nr   r   *.md)r_   rx   r>   rz   r|   r   r   r]   r   r   rK   is_dirwith_suffixr   r   rP   r   r   r0   r=   rglobstem)r   rR   rx   r|   raw_namecandidate_names	namespacebarecandidate_namedirect_path	legacy_mdrL   r   r   _rz   s                  @r   _find_skill_in_dirr     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) / / >1!*k:: 	 	9[:%=$E$E$G$G 	9j 88888++E22	 	/"4Z"K"K 	/#Y....**:zBB  GGGGGGGGG 	O	>X%%h&&&&	//0B0BG0B0T0TUZVZUZ0[\\NKv&&(22 (**** 3 	 	 	H	  %%f-- / /	>Z''>X%%*<Z*S*S%#Y....:s   7AG
GG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>?  s    ]]]q6]]]r   r8      FzSkill 'z' not found.z+Use skills_list to see all available skills)r   erroravailable_skillsr   )r   r0   )r   rR   	availables      r   _skill_not_found_payloadr   >  sa    ]]$9*$E$E$I$I(TV$W$WX[Y[X[$\]]]I-4---%=	  r   c                    ddl m} 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 |r|dz  |k    rt	          |          nt	          |          } ||          }t          |t                    rt          j        |          n|}|S )Nr   )
skill_viewr   r*   )is_valid_namespaceparse_qualified_name)discover_pluginsget_plugin_managerr   )r>   r   rC   r   r   r_   r   r   hermes_cli.pluginsr   r   find_plugin_skilllist_plugin_skills
isinstancejsonloadsr=   r   )r   _skill_viewrR   r   rL   r   r   r   r   r   _barepmr3   target_namedatas                  r   _skill_view_from_active_dirr   H  s   ;;;;;;#%%J,T:>>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$-i9z3Ih2V2V#i...\_`h\i\iK
+k
"
"C(c22;4:c???DKs   BC 
C)(C)   c                 l    t          | pd                                                                          S Nr*   r   
raw_sources    r   _normalize_messaging_sourcer   s  s-    zR  &&((..000r   c                 .    t          |           t          v S rX   )r   _MESSAGING_RAW_SOURCESr   s    r   _is_known_messaging_sourcer   w  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   r6   r:   r;   sessionszsessions.json)
r<   r7   r   rB   rG   r=   r?   r@   r   rA   )r7   hermes_homes     r   _gateway_session_metadata_pathr     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: %s
session_idoriginplatformsession_keykeychat_id	thread_id	chat_typeuser_id)r   r   r   r   r   r   r   )r   r]   statr    _MESSAGING_SESSION_METADATA_LOCKr   st_mtimecopyr=   r   r   r   rr   rs   r   dictr   r   r0   )
r   stcacheraw_sessions	_json_errmapping_entryr   r   r   s
             r   "_load_gateway_session_identity_mapr	    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 rX   )_RUNNING_CRON_LOCKtimer   r
  s    r   _mark_cron_runningr    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 rX   )r  r   popr  s    r   _mark_cron_doner    s    	 - -vt,,,- - - - - - - - - - - - - - - - - -r  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)r  r   r0   r  )r
  ts     r   _is_cron_runningr    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!    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   r*   Nr   z
...
)rQ   r!  r  _CRON_OUTPUT_HEADER_CONTEXTrstriplstrip)r   r"  response_idxheaderresponser   s         r   _cron_output_content_windowr*    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  
setdefaultr0   )r+  rj   s     r   _cron_job_for_apir0    sK     39"ooGy$'''%,[[1F%G%Gu%TG!"Nr   c                     d | pg D             S )Nc                 ,    g | ]}t          |          S r   )r0  )r   r+  s     r   r^   z&_cron_jobs_for_api.<locals>.<listcomp>  s!    ;;;sc"";;;r   r   )jobss    r   _cron_jobs_for_apir4    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_apidefaultr   r*   )r<   r6  r   r0   r   AttributeErrorr   )r6  namesr-  r   s       r   _available_cron_profile_namesr:  	  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   r:  rJ   )r   r-  s     r   _normalize_cron_profile_valuer<    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   )r7   get_hermes_home_for_profiler-  r*   zICron job %s references missing profile %r; falling back to server defaultid?)	r<   r7   r>  r   r0   r   r:  rr   warning)r+  r7   r>  r3   s       r   _profile_home_for_cron_jobrB  "  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.schedulerrE  )rE  r+  s    r   _runz'_cron_job_subprocess_main.<locals>._run:  s#    ......73<<r   Nr   cron_profile_context_for_homeokr   z: )r<   rI  putBaseException	tracebacktype__name__
format_exc)r+  execution_profile_homeresult_queuerG  r   rI  excrM  s   `       r   _cron_job_subprocess_mainrT  7  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     @)r0   float	TypeErrorrJ   max)r+  r   r3   r   s       r   '_cron_subprocess_result_timeout_secondsr^  M  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 resultr*   rX  r   z.cron run subprocess produced no result within gzs and was terminatedz%cron run subprocess exited with code z without producing a resultrJ  z9cron run subprocess did not exit after returning a resultz!Manual cron subprocess failed:
%s)multiprocessingqueueget_contextQueueProcessrT  startr^  r0   Emptyis_alive	terminatejoinexitcodeclosejoin_threadrQ   rr   r   RuntimeError)r+  rQ  rg  rh  ctxrR  processresult_timeoutstatusrj   r   traceback_texts               r   #_run_cron_job_in_profile_subprocessrz  ^  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 m	m |                     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                     d
S # t                     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   )mark_job_runsave_job_outputr?  r*   c                     | 
 |            S ddl m}  ||           5   |            cd d d            S # 1 swxY w Y   d S )Nr   rH  )r<   rI  )rA   fnrI  s      r   _with_cron_homez*_run_cron_tracked.<locals>._with_cron_home  s    <244K>>>>>>**400 	 	244	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   
599c                  R                }} | rsd} d} | |           d S )NFzWAgent completed but produced empty response (model error, timeout, or misconfiguration)r   )	_success_errorr   final_responser
  r|  outputr}  r   s	     r   _persist_successz+_run_cron_tracked.<locals>._persist_success  sU    OFF+++  'fH s s rL622222r   z!Manual cron run failed for job %sc                  8     dt                               S NFr   )r   r
  r|  s   r   <lambda>z#_run_cron_tracked.<locals>.<lambda>  s    ,,vucRSff2U2U r   z-Failed to mark manual cron run failure for %sN)
	cron.jobsr|  r}  r0   rz  r=   rr   	exceptionrs   r  )r+  profile_homerQ  r  r  r   r   r  r
  r|  r  r}  r   s        @@@@@@@@r   _run_cron_trackedr    s    87777777WWT2F3C|   1T'2
 2
.
	3 
	3 
	3 
	3 
	3 
	3 
	3 
	3 
	3 
	3 
	3 	&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 	sS   ,A C 
C	&CBC%B<9C;B<<C?C C		C C.	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  nvidiarY  _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_namer7  z@_active_profile_for_live_models_cache fell back to 'default': %s)r<   r  r=   rr   rs   )r  _es     r   %_active_profile_for_live_models_cacher    sq    	888888&&((5I5    	WY[\\\yyyyys    
A?Aproviderc                 "    t                      | fS rX   )r  )r  s    r   _live_models_cache_keyr     s    133X>>r   r   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 rX   )	r  	monotonic_LIVE_MODELS_CACHE_LOCKr  r0   _LIVE_MODELS_CACHE_TTLr  r  deepcopy)r   nowcachedtsrj   s        r   _get_cached_live_modelsr    s*   
.

C	  & &#'',, 	& & & & & & & & G8---""3---& & & & & & & & }W%%& & & & & & & & & & & & & & & & & &s   B"/B"B""B&)B&rj   c                     t           5  t          j                    t          j        |          ft
          | <   d d d            d S # 1 swxY w Y   d S rX   )r  r  r  r  r  r  )r   rj   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 rX   )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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)
requirebadsafe_resolvejr  	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.  rx  T)r  r   )handlerparsedr  s      r   _kanban_unknown_endpointr  O  sU    O O O O O O     
r   c           
         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| _	        t          | d          rd| _        t          | d          rg | _        t          | d          r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   rp   rn   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.r   r@  pending_user_messagepending_attachmentspending_started_atz7_clear_stale_stream_state: save() failed for session %sT)rh   r  r  
api.modelsrp   r   r=   rr   rA  r  hasattrr  r  r  r  +_materialize_pending_user_turn_before_errorsaver  )ri   	stream_idstream_aliveoriginal_stub_get_sessions        r   _clear_stale_stream_stater  \  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  7.55BB        	4G<<<#' 7233 	0+/G(7122 	-*,G'7011 	.)-G&	LLNNNN 	 	 	Is33    	              ( G##		-1M*}&<== :592}&;<< 7461}&:;; 8370 	 	 	D	4s   
377A/ /5B('B(AD 
DD4HAH4G	H	4H =H?H  HHHAI, ,
I98I9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.Fr   r  is_streamingTrn   z>Failed to load session %s while reconciling stale stream stater   )r   r  r0   rp   r=   rr   rs   r  )session_rowschangedrowrl   ri   s        r   ._reconcile_stale_stream_state_for_session_rowsr    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.)r*   N[]r  r   Nr   )r   r   r   r  isdigitr   rsplit)r   endhostrestports        r   _normalize_host_portr    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   )r	  r
  r  r7  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_ORIGINSr*   ,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   r%  r   r   sysprintstderrr   )r3   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                 8   | j                             dd          }| j                             dd          }| j                             dd          }|s|sdS |p|}t          j        d|          }|sdS |                    d          }|                    d	                              d
          d	                                         }t          |          \  }}	|                    d	                              d                                          }
|
t                      v rdS d || j                             dd          | j                             dd          fD             }|D ].}t          |          \  }}||k    rt          ||	|          r dS /dS )z6Reject cross-origin POST requests. Returns True if OK.Originr*   RefererHostTz^https?://([^/]+)Fr   r   z://r   c                 ^    g | ]*}|                                 |                                 +S r   r   )r   hs     r   r^   z_check_csrf.<locals>.<listcomp>4  s@       
 7799			  r   zX-Forwarded-HostzX-Real-Host)headersr0   _rematchgroupr   r   r  r%  r  r  )r  r   refererr  rc  morigin_hostr	  origin_namer
  origin_valueallowed_hostsallowedallowed_namer  s                  r   _check_csrfr/    s   _  2..Fo!!)R00G?vr**D ' twF	&//A u''!**KGGAJJ$$U++A.4466M3K@@K771::$$S))//11L.0000t  O 2B77Or22
  M !  %9'%B%B"l,&&<{T`+a+a&445r   c                 z    	 t          | dd           }|rt          |d                   S n# t          $ r Y nw xY wdS )Nclient_addressr   unknown)rh   r   r=   )r  addresss     r   _client_ip_for_rate_limitr4  D  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>S  s    WWWR"PV,,b,,,r   TF)	r  r4  %_CSP_REPORT_RATE_LIMIT_WINDOW_SECONDS_CSP_REPORT_RATE_LIMIT_LOCKr#   r0   rQ   _CSP_REPORT_RATE_LIMIT_MAXr   )r  r  r   
timestampsr7  s       @r   _csp_report_rate_limitedr<  N  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 5s   AB<B<<C C    rx  c                     |                      |           |                     dd           |                                  dS )NContent-Length0T)send_responsesend_headerend_headers)r  rx  s     r   _send_no_contentrD  \  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bytess   {}r   T)invalidrH  )intr#  r0   r=   _CSP_REPORT_MAX_BODY_BYTESrfilereadr   r   decoderQ   )r  lengthr3   s      r   _read_csp_report_payloadrP  c  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_LOGGERrA  r4  rD  rP  info)r  rj   s     r   _handle_csp_reportrT  u  s    (( )""=%g..	
 	
 	
  (((&w//G46OPW6X6XZabbbG$$$r   c                     t          | pd                                                                          }|sdS |t          v rt          |         S dD ]\  }}|                    |          r|c S dS )Nr*   ))r  r  )r  r  )r  r  )r  r  )r  r  )r  r  )
openrouterrV  )customrW  )r   r   r   _PROVIDER_ALIASESr   )r   r3   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_idr*   )r   r0   r   r   r   r   r[  )r\  raw_provider_idsnormalized_provider_idsr&  r3   rZ  s         r   _catalog_provider_id_setsrb    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`  ra  c                 "    | |v p|o||v p|o||v S rX   r   )rc  rd  r`  ra  s       r   _catalog_has_providerrf    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[  )rg  rh  model_lowerbare_prefixs       r   %_model_matches_active_provider_familyrm    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 )Nr*   @r   r   r   -.)r   r   r   r  r   replacer   )rE   rg  s     r   _catalog_model_id_matchesrs    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 )Nr*   r7  ro  r   )r   r   r   r   )r   r  s     r   _clean_session_model_providerru    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 )Nr*   ro  r   r   )r   r   r   r  ru  )rg  provider_hint
bare_modelr  r   s        r   _split_provider_qualified_modelry    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_  r*   c              3      K   | ]<}t          |t                    t          |                    d                     V  =dS )r?  N)r   r  rs  r0   )r   entryrg  s     r   r[   z8_should_attach_codex_provider_context.<locals>.<genexpr>  s[       
 
%&&
%eiioou==
 
 
 
 
 
r   models)r   r   r0   r   r   r   )rg  rz  r\  r&  s   `   r   %_should_attach_codex_provider_contextr    s     n,,u;;==##E** uX&&," 
 
uyy''-2..4466<<>>.PP 
 
 
 
8R00
 
 
 
 
 	
 	
 	

 5r   model_idmodel_providerc                    t                      }t          |                    d          pt          pd                                          }t          | pd                                          }t          |          }|s||t          |          fS t          |                    d                    }t          |                    d          pd                                                                          }|s|st          |          \  }}	||	p|dfS t          |          \  }
}	|r|	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	||r||dfS |p|}|r|dvr||k    r|r||dfS ||dfS )a#  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.
    default_modelr*   rh  Fro  r   NTr   r   rj  >   rW  rV  >   r*   rW  rV  r^  c                 V    h | ]&}t          |                    d           pd          'S )r_  r*   )r[  r0   r   rf  s     r   r   z:_resolve_compatible_session_model_state.<locals>.<setcomp>i  s?     !
 !
 !
CD"155#7#7#=2>>!
 !
 !
r   c              3   L   K   | ]}|                     d           pddk    V   dS )r_  r*   rV  Nr   r  s     r   r[   z:_resolve_compatible_session_model_state.<locals>.<genexpr>m  sI       #
 #
=>QUU=!!'RL8#
 #
 #
 #
 #
 #
r   r  r  )r  r   r0   r  r   ru  boolr[  r   ry  r   rb  rf  rm  r  r  r   )r  r  r\  r  rg  requested_providerrh  rz  rx  explicit_providerbare_for_contextrc  rd  r`  ra  hint_matches_activeprovider_contextslashrk  rl  r^  routable_provider_idshas_openrouter_group_active_for_compares                           r   '_resolve_compatible_session_model_stater    s4    #$$GO44KKLLRRTTMB%%''E6~FF 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'' 0"3 0(%// -*(.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&&& ' 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.)r  )r  effective_model	_providerr  s       r   !_resolve_compatible_session_modelr    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 )Nrg  r*   r  Ftouch_updated_at)rh   ru  r  rg  r  r  )ri   original_modeloriginal_providerr  effective_providerr  provider_changeds          r   !_normalize_session_model_in_placer    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.
    rg  Nr*   r  rh   r  )ri   r  r  r  _changeds        r   ,_resolve_effective_session_model_for_displayr    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 )Nrg  r*   r  r  )ri   r  _modelr  r  s        r   5_resolve_effective_session_model_provider_for_displayr    sM    Wgt44:N!H$)400" "FHh Or   r  current_providerc                     | !t          |                                           nd }|t          |          nd }|r<t          |          \  }}|r|}n|t          |          }t	          ||          \  }}}||fS rX   )r   r   ru  ry  r  )rg  r  r  model_valuer  r   r  r  s           r   !_session_model_state_from_requestr    s    
 ).(9#e**""$$$tK ) 	&&8999 
  	
#B;#O#O   	G(HH'45EFFH*Q+
 +
'Xx   r   r   c                     | si S t                                          t          |                     }t          |t                    r|ni S rX   )r	  r0   r   r   r  )r   metadatas     r    _lookup_gateway_session_identityr    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 )Nr   )get_cli_sessionsr0   r=   )r   r  s     r   _lookup_cli_session_metadatar    s~     	#%% 	 	Cww|$$
22


 3	    			Is   ,5 5 AAc                     | sdS t          | t                    r"t          |                     d                    nt          t	          | dd                    }|pt          |           S )zGReturn true when /api/session should pay for Agent/CLI metadata lookup.Fis_cli_session)r   r  r  r0   rh   _is_messaging_session_record)ri   is_clis     r   _needs_cli_session_metadatar    sp     u gt$$	=W[[)**+++''#3U;;<< 
 :1':::r   ri   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 )Nr   r   gateway_session_keyz|session_key:r   origin_chat_idr   r   r   origin_user_idz
chat_type:zchat_id:z
thread_id:zuser_id:|)r  r0   r   r   rp  )	ri   r   r  r   r   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_tagsourcer   source_label	messaging)r   r0   r   ri   r3   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 )Nr   r   r  r   r  r   )r  r0   r  r   )ri   r  s     r   _has_durable_messaging_identityr  6  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   )rJ  r[  r   r\  rJ   r   s    r   _numeric_countr  D  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.
    Fr   
end_reasonTparent_session_idmessage_countactual_message_countr   )r  r   r   r0   _STALE_MESSAGING_END_REASONSr  r  )ri   r  r  r   rl   r  actual_counts          r   $_should_hide_stale_messaging_sessionr  K  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  r  r  )r   r  rh   r0   r   r   r  s     r   r  r  t  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          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)Sessionloadr  r=   r  )rl   ri   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 )Nlast_message_at
updated_at
created_at
started_atr   r  )r[  r   r0   ri   s    r   _session_sort_timestampr    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  r  r*   title)r*   untitledclizcli sessionz sessionr  )	r   r  r   r0   r   r   r   r   endswith)ri   r  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   r   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   )r   r  keptcli_seenri   s        r   _cap_recent_cli_sessionsr    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   r   r   r   r   r   r  r  r  _lineage_root_id_lineage_tip_id_compression_segment_countr  Nr  r  r  r  r  Untitledrg  r2  )r  r   r0   r]  r  )r  r  mergedr   r   current_titles         r   _merge_cli_sidebar_metadatar    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 rX   )r  r   r  r  s     r   _messaging_source_keyr     s4    
'
0
0C%c** t&w444r   c                    t                      }d |                                D             }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.c                 0    h | ]}|t          |          S r   r  )r   rl   s     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>
  s$    !U!U!UsQT!U#c((!U!U!Ur   c           
          h | ]Z}t          |t                    t          t          |                    d           |                    d                              [S )r   r   )r   r  r   r   r0   )r   metas     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>  sc       dD!!#K0F0FQ[H\H\$]$]^^  r   c                 0    h | ]}t          |          |S r   )r   )r   r  s     r   r   z<_keep_latest_messaging_session_per_source.<locals>.<setcomp>  s'    pppMghnMoMopfpppr   NTr   reverse)r	  keysr   r   r  r   r  r   r0   r  r`   sort)
r   gateway_metadatar  r  kept_sourcesbest_by_sourcer  ri   r   currents
             r   )_keep_latest_messaging_session_per_sourcer    s   9;;!U!U6F6K6K6M6M!U!U!U $++--  
 qp3Ippp UUL&(ND & &#G,, 	KK   /9SUkll 	,S!!!$((--G"9'"B"BE\]dEeEe"e"e&-s#%sKK%%''(((II)4I888Kr   )r  rp   new_sessionall_sessions
title_from_write_session_indexSESSION_INDEX_FILE_active_state_db_pathload_projectssave_projectsimport_cli_sessionr  get_cli_session_messagesensure_cron_projectis_cron_session)load_workspacessave_workspacesget_last_workspaceset_last_workspacelist_dir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_streamr  )get_providersget_provider_quota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resolve_gateway_approvalenable_session_yolodisable_session_yolois_session_yolo_enabledc                      d S rX   r   aks     r   r  r  o      $ r   c                      d S rX   r   r<  s     r   r  r  p  s    d r   c                      d S rX   r   r<  s     r   r  r  q  s     r   c                      d S rX   r   r<  s     r   r  r  r  s    t r   c                      dS NTr   r<  s     r   r  r  s  s    $ r   c                      dS r  r   r<  s     r   r  r  t  s    q r   c                      d S rX   r   r<  s     r   r  r  u  r?  r   c                      d S rX   r   r<  s     r   r  r  v  s    4 r   c                      dS r  r   r<  s     r   r  r  w  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.   ra  N)rh  rj  r5  rI  r/  r   )r   qs     r   _approval_sse_subscriberM    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rL  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)r5  rI  r0   remover  )r   rL  subss      r   _approval_sse_unsubscriberQ    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  rI  r0   
put_nowaitrh  Full)r   rR  rS  rj   rP  rL  s         r   _approval_sse_notify_lockedrZ    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)r5  rZ  )r   rR  rS  s      r   _approval_sse_notifyr\    s     
 = =#Je<<<= = = = = = = = = = = = = = = = = =s   '++r   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  r/  uuiduuid4hexr5  r4  r   listr   rQ   rZ  )r   r]  r}  
queue_listrS  rR  s         r   r/  r/    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sse_subscribesse_unsubscribec                      d S rX   r   r<  s     r   r  r    s    T r   c                      d S rX   r   r<  s     r   r  r    r?  r   c                      dS r  r   r<  s     r   r  r    s    a 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   연결 실패)rl  fresderuzhzh-Hantitjaptko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.rl  r   rp  r~  zzh-cnzzh-sgzzh-hanszzh-twzzh-hkzzh-mozzh-hantr  r   r   )r   r   _LOGIN_LOCALErr  r   r   r   )r  ro  rZ  r   r   bases         r   _resolve_login_locale_keyr  V  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)}
.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>
  </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   )rJ  r   r   r\  rJ   _LOG_DEFAULT_TAIL_LOG_TAIL_VALUES)raw_tailtails     r   _normalize_logs_tailr    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  r  r  Nr6   r:   r;   logsF)strictzInvalid log filezLog file for z not found yet.)r  r  lines	truncatedtotal_bytesr   r   rbr   rr  )r  r*   z&Failed to read whitelisted log file %sr  )#r   r/   r0   r   r   _LOG_FILE_WHITELISTr  r  r<   r7   r   rB   r=   r?   environrA   rG   r   r]   is_filer  r   rJ  st_sizer  _LOG_MAX_BYTESopenseekrM  rN  
splitlinesr   rr   r  r  )r  r  r/   file_keyfilenamer  r7   r   log_dirlog_pathr  r  
read_bytesfhr3   r   r  rS  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   r6   r:   r;   )	r<   r7   r   rB   r=   r?   r@   r   rA   r6   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r   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   rr  r   r  r   =r   	WIKI_PATH"')r]   r  r   r  r   r   r   r=   )r   env_pathr   strippedr   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 )Nrq  )r   r  r0   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   
get_configskills.config.wiki.pathz	wiki.path)
api.configr  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 rX   )r   r   rB   rG   rY   s     r   r[   r[   %	  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  r7  r  Tz~/wiki)
r  r?   r@   r  r  r  r   r   
expandvarsrB   )r   r3   r  
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	isoformatrr  r=   )r  r  r  s      r   _llm_wiki_safe_isor  9	  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   c              3   @   K   | ]}|                     d           V  dS rq  Nr   r   r   s     r   r[   z(_llm_wiki_count_files.<locals>.<genexpr>U	  s.      )h)h4$//#*>*>)h)h)h)h)h)hr   )r]   r   r   rG   _LLM_WIKI_FORBIDDEN_ROOTSr=   r   _LLM_WIKI_MAX_FILESr  r   rH   rP   )r  r   iterateditems       r   _llm_wiki_count_filesr  C	  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   r[   z'_llm_wiki_page_files.<locals>.<genexpr>o	  s.      -Y-Ytdooc.B.B-Y-Y-Y-Y-Y-Yr   )r   rG   r  r=   _LLM_WIKI_PAGE_DIRSr]   r   r   r  rH   r  r   rP   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   enabledrx  entry_count
page_countraw_source_countlast_updatedlast_writerpath_configuredpath_sourcetoggle_availabletoggle_reasondocs_urlnot_directoryrx  c                 b    g | ],}|                                 |                                *|-S r   )r]   r  rY   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emptyr3   )r   r  rx  r  r  r  r  r   r2  z)Unable to inspect LLM Wiki status safely.)r   r  rx  r  r  r  r  r  r  r  r  r  r  r   )r  _LLM_WIKI_DOCS_URLr]   r   r  r`   r   r   r=   r]  updaterQ   r  r  rN  rO  )
r  r  r  r  
page_filesstatus_fileslatestr  r   rS  s
             r   _build_llm_wiki_statusr  v	  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 rD  )r  r  )r  r  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   im     iQ r'   c                     	 t          t          t          | pd                    d          S # t          t          f$ r Y dS w xY wr  )r]  rJ  r[  r\  rJ   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)Nr  $r*   r  )r   r   r   rr  r]  r[  r\  rJ   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ri   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  r  input_tokensoutput_tokensestimated_costr  rg  r2  )r   r  r  costr   r  z%Y-%m-%d)r  r  r   r     r%   )	rg  r   r  r  total_tokensr  session_sharetoken_share
cost_sharec                 4    | d          | d          | d         fS )Nr  r   rg  r   )rs    r   r  z"_handle_insights.<locals>.<lambda>>
  s    !F)a
m^QwZ(P r   r   )dater  r  r   r  )MonTueWedThuFriSatSunc                 N    g | ]!}|                              |d           d"S )r   )dayr   r   )r   idow_activity
dow_labelss     r   r^   z$_handle_insights.<locals>.<listcomp>T
  s5    ]]]q
1<3C3CAq3I3IJJ]]]r      c                 B    g | ]}|                     |d           dS )r   )hourr   r   )r   r"  hod_activitys     r   r^   z$_handle_insights.<locals>.<listcomp>W
  s1    SSSA(8(8A(>(>??SSSr      )period_daystotal_sessionstotal_messagestotal_input_tokenstotal_output_tokensr  
total_costr~  daily_tokensactivity_by_dayactivity_by_hour)%collectionsr  r   r/   r  r]  rJ  r0   rJ   r\  	localtimemktimetm_yeartm_montm_mdaytm_wdaytm_ydaytm_isdstr[  r  r  r]   r   r   r   r=   r   rQ   Counterr/  strftimetm_houritemsroundr  ranger  )3r  r  r6  _timer/   r  r  todaytoday_midnightday_secsfirst_day_tsr7  r	  r  r  sessions_dataidx_pathr   r}  createdupdatedr.  r/  r0  r1  r2  model_statsr3  r   r  r  
cost_valuerg  bucketr  dtday_keydaily_bucketr  models_breakdownstatsrow_total_tokensrow_costdaily_seriesr%  day_tsdow_datahod_datar&  r'  r+  s3                                                   @@@r   _handle_insightsr\  	  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_atr  rO   )requests_totallast_request_at)rh   rJ  rC  r[  )r  r^  s     r   _accept_loop_healthrc  k
  sj    Wh--Fgf.JANNSRSTT wv7TVY'Z'Z'a^a!b!bdeff  r         ?rV  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)Nre  r  r   blocked)rx  rV  msrJ  )rx  active_streamsrg  )r  r  acquirerC  rQ   r  release)rV  t0acquired
elapsed_mss       r   _streams_lock_healthrn  s
  s    	B#O<<<H	b(D0!44J 
.
 
 	

!'ll
 
 	s   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  r  r  r   age_secondsNc                 J    t          |                     d          pd          S )Nr  r  )r[  r0   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  r  ACTIVE_RUNS_LOCKACTIVE_RUNSrB  r  r0   r]  r[  r=   r/  rC  r   LAST_RUN_FINISHED_ATr  rQ   )
_live_configr  rt  r  r3   r  r  agelast_finishedrj   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                 X   i }| | n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_lockrx  rJ  Fr  r   )rx  r   rg  r   r   )rx  r   rg  )_migrateprojectsr  )rx  rg  state_dbzPRAGMA schema_versionc              3   D   K   | ]}|                     d           dv V  dS )rx  >   rJ  r  Nr   )r   checks     r   r[   z&_deep_health_checks.<locals>.<genexpr>
  sH         			(00     r   )rn  r0   r  r  rQ   rC  r=   rN  rO  r  r
  r]   r   sqlite3connectr   executefetchoneallr   )	r  checksrk  r   rS  r  db_pathconnhealthys	            r   _deep_health_checksr  
  s    !F-9-E\\K_KaKaF>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 
C-#A C((C-AE 
F$A FF$;A>J& 9(I-!J& -I11J& 4I150J& &
K:0A K55K: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 )Nr*   deepr   >   r+   r.   r-   r,   rx  rJ  degradedrh  rs  rt  ru  r   )rx  r   rh  rs  rt  ru  uptime_secondsaccept_looprv  rw  r  r    r  )r  )r   r/   r0   r   rn  r  rQ   r  rJ  rC  r  r  rc  r  r  )r  r  r  r  	run_checkrj   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.Nr*    r  r      …)r   rr  r   rp  r   rQ   r%  )r   r"  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          }	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|||	t          t          |dd                    |
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.
    Fforce_pluginsc                 ,    t          | d                   S r  r  rr  s    r   r  z,_plugin_visibility_payload.<locals>.<lambda>A  s    CQLL r   r  manifestNr   r   r*   x   r  versionP   r   i  provides_hookshooks_registeredr  )r   r   r  r   r  hooksT)pluginsr  supported_hooks	read_only)r  discover_and_loadrh   r   rB  r  rc  r   r   _PLUGIN_VISIBILITY_HOOK_SETr   r  _PLUGIN_VISIBILITY_HOOKSindexr  )managerr  raw_pluginsr   loadedr  
plugin_keyr   r  r   
registeredhook	hook_names                r   _plugin_visibility_payloadr  3  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
+;R@@FBGG$wW]_qsuOvOvO|z|J}J}} 	- 	-DDJB--//I777IZ<W<W!!),,,4:;;;%&GFIu==>>
 
 	 	 	 	 ']]" 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=   rr   rA  rc  r  )r  r  rS  s      r   _handle_pluginsr  c  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>rS  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)rx  content_typeT)rr   rA  r  _SHELL_ERROR_HTML)r  rS  s     r   _serve_shell_unavailabler    sA    
NN:C@@@/	    4r   c                 \   |j                             d          r@|                    |j         t          d          d                   }t	          | |          S |j         dv s|j                             d          r	 ddlm} dd	lm}  ||d
          }ddl	m
} t          j        d                              d|          }t          |  ||          d          S # t          $ r}t!          | |          cY d}~S d}~ww xY w|j         dk    r!t#                      }	t%          j        |	                    d          pd          }
|	                    dd          }t*          t-          |                   }ddlm} dd	lm}  ||d
          }t.                              d|
                              d|
d                                                                       d|                              dt%          j        |d                                                 dt%          j        |d                                                 dt%          j        |d                                                 d t%          j        |d!                                                 d"t%          j        |d#                                                 d$t%          j        |d%                                                 d&t%          j        |d'                             }t          | |d          S |j         d(k    rVdd)lm}m}m} d*} |            r% ||           }t;          |o
 ||                    }t=          |  |            |d+          S |j         d,v rt?          t@                    j!        j!        d-z  }|d.z  "                                }|#                                r|$                                }| %                    d/           | &                    d0d1           | &                    d2d3           | &                    d4tO          t          |                               | (                                 | j)        *                    |           d5S t=          | d6d7id89          S |j         d:k    rpt?          t@                    j!        j!        d-z  }|d;z  "                                }|#                                rddlm} dd	lm}  ||d
          }|                    d                              d|          }|+                    d          }| %                    d/           | &                    d0d<           | &                    d2d3           | &                    d=d>           | &                    d4tO          t          |                               | (                                 | j)        *                    |           d5S t=          | d6d7id89          S |j         d?k    r?t?          t@                    j!        j!        d-z  }|d@z  "                                }|#                                r|,                                r|$                                }| %                    d/           | &                    d0dA           | &                    d4tO          t          |                               | &                    d2dB           | (                                 | j)        *                    |           n)| %                    dC           | (                                 d5S |j         dDk    rt[          | |          S |j                             dE          r)ddFl.m/}  || |          }|d*u rta          | |dG          S d5S |j         dHk    rtc          | |          S |j         dIk    rte          | |          S |j         dJk    rtg          | |          S |j         dKk    rt=          | ti                                S |j         dLk    rt=          | tk                                 d5S |j         dMk    rt=          | tm                                S |j         dNk    rto          | |          S |j         dOk    r*ddPl8m9} t=          | |:                                           d5S |j         dQk    rbddPl8m9} 	 t=          | |;                                           n6# tx          $ r)}t{          | tO          |          dR9           Y d}~nd}~ww xY wd5S |j         dSk    rt=          | t}                                S |j         dTk    rt          | |          S |j         dUk    rPt          |jA                  }|                    dVd
g          d         pd}t=          | t          |                    S |j         dWk    rt#                      }|C                    dXd           t;          t          jE        dYd
          F                                          |dZ<   	 dd[lmG}m} ||d\<   ||d]<   n# t          $ r Y nw xY wt=          | |          S |j         d^k    rt=          | t                                S |j         d_k    rt=          | t                                S |j                             d`          rddal	mJ}   | | |          S |j                             db          rt	          | |          S |j         dck    rt          |jA                  }|                    ddd
g          d         }!|!st{          | dedR9          S 	 t          |!d5f          }"n"# t          $ r t{          | dgd89          cY S w xY w	 ddhlMmN}# t=          | di |#|"          i          S # tx          $ r)}t{          | tO          |          dR9          cY d}~S d}~wt          $ rD}t          P                    dj|!           t{          | t          |          dk9          cY d}~S d}~ww xY w|j         dlk    r?t          |jA                  }t          | |                    ddd
g          d                   S |j         dmk    
rddlS}$|$T                                }%t          jU                            dnd
          }&t          |jA                  }|                    ddd
g          d         }!|!st=          | d6deidR9          S |                    dodpg          d         dqk    }'|'rdpndq}(|                    dr|(g          d         dqk    })|                    dsdg          d         }*	 |*rt          dtt          |*                    nd}+n# tx          t          f$ r d}+Y nw xY w|                    dudg          d         },	 |,rt          |,          nd}-n# tx          t          f$ r d}-Y nw xY w	 |$T                                }.t          |!|' f          }"t          |"           t          |"          rt          |!          ni }/t          |"          pt          |/          }0g }1|0rt          |!          }1|$T                                }2|)rt          |"          nd}3|)rt          |"          nd}4|$T                                }5|'r|0r|1rt          |"dog           pg }6|6r|6|1k    r|g }7t                      }8t          t          |1          t          |6          z   dv w          D ]8}9|9                    dx          p|9                    dy          }:|:rdytO          |:          f};ndztO          |9                    d{          pd
          tO          |9                    d|          pd
          tO          |9                    d}          pd
          tO          |9                    d~          pd
          tO          |9                    d          p|9                    d          pd
          f};|;|8v r|8d                    |;           |7e                    |9           :|7}<n/t          |6          t          |1          k    r|6n|1}<n
|"jf        }<ng }<|'rx|-Rt          dt          t          |-          t          |<                              }=|<d|=         }>|+r|>|+ d         n|>}?n&|+rt          |<          |+k    r|<|+ d         }?n|<}?n|<}?t          |"dd          pd}@|@slt          |"dd
          p|3pd
F                                }A|ArB	 ddlhmi}B ddljmk}C  |C            }Dd}Ed}F	 t          |Dt                    r|D                    di           ni }Gt          |Gt                    rG|G                    d          }H|H0	 t          |H          }I|Idk    r|I}En# t          tx          f$ r Y nw xY wt          |Dt                    r|D                    d          nd}Jt          |Jt                    r|J}Fn# t          $ r Y nw xY w	  |B|Ad
|E|4pd
|F          pd}Kn# t          $ r  |B|Ad
          pd}KY nw xY w|Kr|K}@n# t          $ r Y nw xY w|"n                                |?|'rt          |"dg           ng t          |"dd          t          |"dd          |'rt          |"dg           ng t          |"dd          |@t          |"dd          pdt          |"dd          pdd	z  }L|/rt          |/          rt          |L|/          }L|-|'o|+duot          |>          |+k    }Mn|'o|+duot          |<          |+k    }M|M|Ld<   |-$t          d|=t          |?          z
            |Ld<   n0t          dt          |<          t          |?          z
            |Ld<   |$T                                }N|3r|3|Ld<   |4r|4|Ld<   t          |L          }O|$T                                }Pt=          | d|Oi          }Q|$T                                }R|&rEt          q                    d|!|2|.z
  dz  |5|2z
  dz  |N|5z
  dz  |P|Nz
  dz  |R|Pz
  dz  |R|%z
  dz             |QS # t          $ r t          |!          }/t          |!          }S|Sri dd|!d|/pi                     dd          d|/pi                     dd
          d|/pi                     dd          dt          |S          d|/pi                     dd          d|/pi                     dd          d|/pi                     d          p9|/pi                     dd          p!|Sr|Sd         nd}di                    d}d          dd*dd*ddd|/pi                     d          dd5d|/pi                     d          d|/pi                     d          d|/pi                     d          d|/pi                     d          t;          |/pi                     d                    |Sg d}Tt          |T|/          }Tt=          | dt          |T          i          cY S t{          | dgd8          cY S w xY w|j         dk    rt          |jA                                      ddd
g          d         }!|!st{          | ddR          S t          t                      |!          }U|U                    d          st{          | dgd8          S t=          | |U          S |j         dk    r2ddltmu}V t=          |  |Vt          t                                          S |j         dk    rt          |jA                                      ddd
g          d         }!|!st{          | d          S 	 ddlwmx}W t          t          |!d5f                     t=          |  |W|!                    S # t          $ r t{          | dgd8          cY S w xY w|j         dk    r`t          |jA                                      ddd
g          d         }!|!st{          | d          S t=          | dt          |!          i          S |j         dk    rt          |jA                                      ddd
g          d         }!|!st{          | d          S 	 ddlwmz}X t=          |  |X|!                    S # t          $ r t{          | dgd8          cY S w xY w|j         dk    rbt          |jA                                      ddd
g          d         }!|!st{          | d          S ddl{m|}Y t=          | d |Y|!          i          S |j         dk    rat          j~        dG|j         t                    }Z	 |Z                    d           t          |Z          }[|Z                    d           t          |[          r&|Z                    d           t          |Z          }[|Z                    d           t#                      }t;          |                    d                    }\|\rT|Z                    d           t                      }]|Z                    d           d |]D             }^|[D ]}"|^                    |"                    dd                    }_|_s-t          |_          rh|"                    t          |"|_                     |"                    dd          |_                    dd          k    r|_                    dd          |"dd<   dD ]7};|"                    |;          s |_                    |;          r|_|;         |"|;<   8dĄ |[D             }[dń |[D             ddlm fdǄ|]D             }`n#|Z                    dȦ           dɄ |[D             }[g }`|Z                    dʦ           |[|`z   }a|a                    d˄ d5̦           |Z                    dͦ           ddlm}b  |b            t          |          }c|Z                    dϦ           |cr|a}dd}en-fdЄ|aD             }dt          |a          t          |d          z
  }e|Z                    dѦ           t          |d          }d|\r-|Z                    dҦ           t          |dt          Ӧ          }d|Z                    dԦ           g }f|dD ]g}"t          |"          }gt          |g                    d          tN                    rt          |gd                   |gd<   |fe                    |g           h|Z                    dզ           t=          | |ft          |`          |c|et          jS                    t          j        d֦          dל          |Z                                 S # |Z                                 w xY w|j         dk    rtddlm}b  |b            t!                      }ht          |          }c|cr|h}dnfdل|hD             }dt=          | |d|ct          |h          t          |d          z
  dڜ          S |j         dk    rt#          | |          S |j         dk    r-t=          | t%                      t'                      dݜ          S |j         dk    rRt          |jA                  }i|i                    dd
g          d         }jt=          | t)          |j          |jd          S |j         dk    rt+          | |          S |j         dk    rt-          | |          S |j         dk    rddljm}k  |k             ddljmk}l  |l            }m|m                    di           }n|n                    di           }og }pt          |ot                    r|o                                D ]\  }q}rd
}st          |rt                    r|r                    dd
          }sn7t          |rtN                    r"|rdd         t          |r          dk    rdnd
z   }s|pe                    |q|sd           t=          | d|pi          S |j         dk    rt          |jA                  }i|i                    ddd
g          d         }!|!st{          | d          S 	 t          |!          }"n!# t          $ r t{          | dgd8          cY S w xY wddlm}t  |tt?          |"j                            }ut=          | d|ui          S |j         dk    r ddlm}v t=          | d |v            i          S |j         dk    rt#                      }|                    dd5          st=          | dd5i          S t          |jA                  }i|i                    ddqg          d         dpk    }w|i                    ddqg          d         dpk    r1| j        d         dk    r t=          | ddddddddtdddddd          S dd lm}x t=          |  |x|w                    S |j         dk    rLt          |jA                                      dd
g          d         }yt=          | |yt@          v |yd          S |j         dk    rht          |jA                                      dd
g          d         }y|yst{          | d          S tC          |y          }zt=          | d5|z|yd          S |j         dk    rtE          | |          S |j         d	k    rtG          | |          S |j         d
k    rtI          | |          S |j         dk    rtK          | |          S |j         dk    rtM          | |          S |j         dk    rtO          | |          S |j         dk    rtQ          | |          S |j         dk    rtS          | |          S |j         dk    r6| j        d         dk    rt=          | d6d7id89          S tU          | |          S |j         dk    rtW          | |          S |j         dk    rtY          | |          S |j         dk    r6| j        d         dk    rt=          | d6d7id89          S t[          | |          S |j         dk    rt          |jA                  }i|i                    dd
g          d         }{	 t=          | t]          |{          d2d3i          S # tx          $ r'}|t{          | tO          ||                    cY d}|~|S d}|~|wt          $ r(}|t{          | tO          ||          d8          cY d}|~|S d}|~|ww xY w|j         dk    r\ddlm}} ddlm}~  |~            5  t=          | dte           |}d5                    i          cddd           S # 1 swxY w Y   |j         dk    r:ddlm}~  |~            5  tg          | |          cddd           S # 1 swxY w Y   |j         dk    r:ddlm}~  |~            5  ti          | |          cddd           S # 1 swxY w Y   |j         dk    r:ddlm}~  |~            5  tk          | |          cddd           S # 1 swxY w Y   |j         dk    r:ddlm}~  |~            5  tm          | |          cddd           S # 1 swxY w Y   |j         d k    r:ddlm}~  |~            5  to          | |          cddd           S # 1 swxY w Y   |j         d!k    rzt          |jA                  }i|i                    d"dg          d         }tq          ts                      |#          }t=          | d$|                    d$g           i          S |j         d%k    rt          |jA                  }i|i                    dd
g          d         }q|qst=          | d6d&idR9          S |i                    d'd
g          d         }|r#ddl} |j        d(|q          rt{          | d)dR          S ts                      }ty          |q|          \  }}|st{          | d*d8          S ||z  "                                }	 |                    |"                                           n"# tx          $ r t{          | d+dR          cY S w xY w|#                                r|,                                st{          | d,d8          S t=          | |                    d          |d-          S t}          |q          }t          |                    d.          t                    si |d.<   t=          | |          S |j         d/k    rt          |           S |j         d0k    r-dd1lm}m}b t=          |  |             |b            d2          S |j         d3k    r:dd4lm}bm} t=          |  |b            tO           |                      d5          S |j         d6k    rddl}t                      }t                      }ti                      }|                    d7          }|d5u rd5}d5}n|d*u rd*}d5}nt;          |          }d*}t                      }|                                D ]V}_|_                    d          p|_                    d8          pd
}Lt          |L          }|r|d                    |           Wd9d:d;d<d=d>t          fd?|D             d@ w          }d
}|rk|#                                rW	 |                                j        }|j                            |                                          }n# t          $ r Y nw xY wt=          | ||||t          |          dA          S |j         dBk    rt          |           S |j         dCk    rt          |           S |j         dDk    rt          |jA                  }i|i                    dd
g          d         }|st{          | dE          S 	 ddFlm} t=          |  ||                    S # tx          $ r'}|t{          | tO          ||                    cY d}|~|S d}|~|wt          $ rD}|t          P                    dG           t{          | tO          ||          dk9          cY d}|~|S d}|~|ww xY w|j         dHk    rt          |jA                  }i|i                    dd
g          d         }|i                    dId
g          d         }|r|st{          | dJ          S 	 ddKlm} t=          |  |||                    S # tx          $ r'}|t{          | tO          ||                    cY d}|~|S d}|~|wt          $ rD}|t          P                    dL           t{          | tO          ||          dk9          cY d}|~|S d}|~|ww xY wd*S (M  z>Handle all GET routes. Returns True if handled, False for 404.z/session/static/z/sessionNr   )r   z/index.htmlz	/session/r   )quote)WEBUI_VERSIONr*   safe)inject_extension_tagsr   r   __WEBUI_VERSION__r  )r  z/loginbot_nameHermeslanguagerl  z{{BOT_NAME}}z{{BOT_NAME_INITIAL}}z{{WEBUI_VERSION}}z{{LANG}}ro  z{{LOGIN_TITLE}}r  z{{LOGIN_SUBTITLE}}rp  z{{LOGIN_PLACEHOLDER}}rq  z{{LOGIN_BTN}}rr  z{{LOGIN_INVALID_PW}}rs  z{{LOGIN_CONN_FAILED}}rt  z/api/auth/statusis_auth_enabledparse_cookieverify_sessionF)auth_enabled	logged_in)z/manifest.jsonz/manifest.webmanifeststaticzmanifest.jsonr   Content-Typez(application/manifest+json; charset=utf-8Cache-Controlno-storer?  Tr   	not foundr  r  z/sw.jszsw.jsz%application/javascript; charset=utf-8zService-Worker-Allowedr   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/dashboard/statusdashboard_probe/api/dashboard/configr  /api/providersz/api/pluginsz/api/provider/quotar  /api/settingspassword_hashHERMES_WEBUI_PASSWORDpassword_env_var)AGENT_VERSIONr  webui_versionagent_version/api/reasoningz/api/onboarding/statusz/extensions/)serve_extension_static/static/z/api/session/worktree/statusr   session_id is requiredrn   Session not found)worktree_status_for_sessionrx  z-failed to read worktree status for session %sr  z/api/session/compress/statusz/api/sessionHERMES_DEBUG_SLOWmessagesr+   r@  resolve_model	msg_limitr   
msg_beforec                     t          |                     d          pd          t          |                     d          pd          t          |                     d          pd          fS )N	timestampr   roler*   r   )r[  r0   r   )r(  s    r   r  zhandle_get.<locals>.<lambda>  s\    !!%%"4"4"9::f 344i 0 0 6B77f r   r  r?  
message_idlegacyr  r   r  tool_call_id	tool_namer   context_lengthrg  )get_model_context_lengthr  custom_providers)config_context_lengthr  r  
tool_callsr  r  r  r  threshold_tokenslast_prompt_tokens)	r  r  r  r  r  r  r  r  r  _messages_truncated_messages_offsetr  ri   zx[SLOW] session_id=%s get_session=%.1fms model_resolve=%.1fms compact=%.1fms redact=%.1fms json_write=%.1fms total=%.1fmsr  CLI Session	workspacer2  r  r  r  r  r  pinnedarchived
project_idr-  r  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rr   r  diagreconcile_stale_stream_state)all_sessions_after_stale_stream_reconciler  show_cli_sessionsr  merge_cli_sessionsc                      i | ]}|d          |S r   r   r   s     r   
<dictcomp>zhandle_get.<locals>.<dictcomp>  s    ===AQ|_a===r   )r  r   r  r  c                 0    g | ]}t          |          |S r   r	   r   s     r   r^   zhandle_get.<locals>.<listcomp>  s'    !]!]!]?YZ[?\?\!]!!]!]!]r   c                     h | ]
}|d          S r"  r   r   s     r   r   zhandle_get.<locals>.<setcomp>  s    EEEQ|_EEEr   )_hide_from_default_sidebarc                 \    g | ](}|d          vt          |           |          &|)S r"  r%  )r   r   
_cron_hide	webui_idss     r   r^   zhandle_get.<locals>.<listcomp>  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-  r&   r0   )r   r   r/  s     r   r^   zhandle_get.<locals>.<listcomp>  sJ     P P P,QUU9-=-=~NNP! P P Pr   messaging_deduper  )r  redact_sessionsresponse_writez%z)r   	cli_countr)   r/  other_profile_countserver_time	server_tzz/api/projectsc                 Z    g | ]'}t          |                    d                     %|(S r2  r3  )r   rZ   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  r)   r/  r8  z/api/session/exportz/api/workspaces)
workspaceslastz/api/workspaces/suggestrY  )suggestionsrY  z/api/sessions/searchz	/api/listz/api/personalitiesreload_configr  personalitiesr   r  r   )r   r   z/api/git-info)git_info_for_workspacegitz/api/commands)list_commandscommandsz/api/updates/checkcheck_for_updatesr   r  simulatez	127.0.0.1webuirO   abc1234def5678master)r   behindcurrent_sha
latest_shabranchaaa0001bbb0002)rH  r  
checked_at)rF  r  z/api/chat/stream/statusr  )activer  z/api/chat/cancelzstream_id required)rJ  	cancelledr  z/api/chat/streamz/api/terminal/outputz/api/sessions/gateway/streamz
/api/mediaz/api/file/rawz	/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_contextr3  include_disabledz/api/crons/outputz/api/crons/history/api/crons/runz/api/crons/recentz/api/crons/statusz/api/skillsru   r   r8   z/api/skills/contentname requiredr  z[*?\[\]]Invalid skill nameSkill not foundzInvalid file pathFile not found)r   r   linked_filesz/api/memoryz/api/profiles)r6  r  )profilesrS  z/api/profile/active)r  r7   )r   r   z/api/gateway/statusaliver   TelegramDiscordSlackWebAPI)telegramdiscordslackwebrx  c                 f    g | ]-}|                     ||                                          d .S ))r   label)r0   r  )r   rZ   _PLATFORM_LABELSs     r   r^   zhandle_get.<locals>.<listcomp>R  s:    ]]]!a"2"6"6q!''))"D"DEE]]]r   c                     | d         S )Nrp  r   )xs    r   r  zhandle_get.<locals>.<lambda>S  s
    !G* r   )runningr  	platformslast_activesession_countz/api/mcp/serversz/api/mcp/toolsz/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   _replacerQ   _serve_staticurllib.parser  api.updatesr  api.extensionsr  r  r   rr  r  r=   r  r  _htmlescaper0   r  r  _LOGIN_PAGE_HTMLupperapi.authr  r  r  r  r  r   __file__r   rG   r]   r  rA  rB  r   rC  wfilewriteencoder  r\  api.kanban_bridger  r  r  r  r  r  r  r  _handle_live_modelsrx  r  get_dashboard_statusget_dashboard_configrJ   r  r$  r  r   r/   r%  r  r?   r@   r   r  r  r)  r  rp   rq   api.worktreesr  rr   r  r  _handle_session_compress_statusr  r  r  r]  rJ  r\  r  r  r  r  r  r  r  rh   r   r   rc  r   r   r  r  agent.model_metadatar  r  r  r   r  compactr  r  rA  r
   r
  api.session_recoveryr  r  api.session_opsr  r:  r  api.backgroundr  r  maybe_startstager  r  r  r  r  r'  r  r<   r  r4   r  r  CLI_VISIBLE_SESSION_CAPr  r@  finishr  _handle_session_exportr  r  r  _handle_sessions_search_handle_list_dirr@  rB  api.workspacerB  r  api.commandsrD  r1  rF  r  r#  _handle_sse_stream_handle_terminal_output_handle_gateway_sse_stream_handle_media_handle_file_raw_handle_file_read_handle_approval_pending_handle_approval_sse_stream_handle_approval_inject_handle_clarify_pending_handle_clarify_sse_stream_handle_clarify_injectr-  r  rY  r[  r4  _handle_cron_output_handle_cron_history_handle_cron_run_detail_handle_cron_recent_handle_cron_statusr   rC   researchr   rH   r   _handle_memory_readr6  r7   r  r	  r   r   r   r   r   r  r  _handle_mcp_servers_list_handle_mcp_tools_listapi.rollbackrx  rz  )r  r  r  r  r  version_tokenr  htmlrS  	_settings_bn_lang_login_strings_pager  r  r  r  cvstatic_rootmanifest_pathr   sw_pathr   ico_pathr  r   r  r/   r_  settingsr  r  rl   r   r  rE  _t0_debug_slowload_messagesresolve_model_defaultr  
_msg_limitr  _msg_beforer  _t1r  is_messaging_sessioncli_messages_t2r  r  _t3sidecar_messagesmerged_messagesseen_message_keysmsgmessage_identityr   	_all_msgs_before_idx_slice_truncated_msgs_persisted_cl_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_load_fb_clr3   
_truncated_t4redact_t5resp_t6msgssessreportr  r  r  r  r  webui_sessionsr  r  	cli_by_idr  deduped_clir  r  r)   scopedr8  safe_mergedr  all_projectsr2   rY  _reload_cfgr  _cfg	agent_cfgraw_personalitiesrA  r   r   descrB  rS  rD  r  rF  r  rT  rU  r   rY  r[  ru   	file_pathr$  rR   r   	_skill_mdrc  r6  r7   r  identity_mapsessions_pathhealthre  rt  r  platforms_setnormru  rv  r   r  rx  ry  rz  rq  r)  r/  r*  s                                                                                                                                                           @@@@r   
handle_getr    s6    {011 0 ??C
OO4D4D(E?FFWh///{***fk.D.D[.Q.Q*	:******111111!E-b999M<<<<<<#-w???GGH[]jkkD%%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{(((JJJJJJJJJJ	? 	8g&&BR6NN2$6$677I??+<+<9UUVVV{AAA8nn+2X=$6??AA!! 	 ++--D!!#&&&0Z[[[<<< 0#c$ii..AAA!!!M%%%47K0===={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{---''''''	'?7799:::t{---''''''	/g;;==>>>> 	/ 	/ 	/S#.........	/t {&&&-//*** {n$$w///{+++&&yybT2215=,[99:::{o%% ??_d+++
 (,I-r2288::(
 (
#$
	@@@@@@@@(5H_%(5H_%% 	 	 	D	(###{&&& .00111{.../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&&.w		,QSPT8U8UVW8XYYY{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	R	://##CCM0ACCCA%a(((<WXY<Z<Zb3C888`bH#?#B#B#lFbckFlFl L# =7<<//##C !<Q???  !EaHHH 
 //##C (' %+L %+'.q*b'A'A'GR$ ( t,<,L,L*,,/EE)#)$|*<*<tDT?U?U*U \ \ $ $ $ 8 8C
 03wwt}}/U@U@U,/ 
"'3S9I5J5J&K %-$'(=2$>$>$'	(:(:(@b$A$A$'(<(<(B$C$C$'(?(?(E2$F$F$'(<(<(U(USU$V$V'"  #&777 (-11#666+2237777$3		8;<L8M8MPST`PaPa8a8a$4$4gs		 !
II	 ,) #&aS__c)nn)M)M"N"NK&||4F=F&RfiZ[[&9&9FOO 03y>>I#=#=&/
&<OO&/OO"+ $A'7;;@qM  )Aw++DD"%'' " % %$\\\\\\OOOOOO&8&8&:&:,0)592!NXYdfjNkNk.skoogr.J.J.JqsO)/4@@ -4C4G4GHX4Y4Y 1#4#@%-7:;L7M7M+7!+;+;@L,=,5z+B %- %- %-(,%-R\]hjnRoRo+y;??;M+N+N+NuyL),== J=I :( ! ! ! D!
I%,W 1 "6G);)Ar1K& & & &# "# #F  ) I I I%,W->%C%C%HqFFFI " 3,2M$   ))+++>KSgar:::QS$+A/A4$H$H(/3I4(P(PP]'ewq2G'L'L'Lce&-a1Et&L&L"/$+A/A1$E$E$J&-a1Eq&I&I&NQ
! 
! 
C  A8BB A1#x@@
 %*`y/D`VW`I`

*cy/DcYZcIc
)3C%& %*-as??S?S1S*T*T&''*-aY#oBVBV1V*W*W&'//##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\	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)***>vFFF  [

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{*** 	<;;;;;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	:888888%%d1;&7&7885$-((({o%%......:}}7888{*** ??||/66 	2Wz40111fl##w&&q)S0 FF:u%%a(C//&q)[88 !("#'0&/"*  !("#'0&/"*  #$   ( 	211111++%888999{///V\**..{RDAA!D	Y'%9	RRSSS{(((V\**..{RDAA!D	 	6w 4555!),,	IIVVWWW{(((!'6222{,,,&w777{444)'6:::{l""Wf---{o%%000{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 {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#5dJ#G#G 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J"%%% '')) 	( 	(D((<((FDHHZ,@,@FBC.s33D (!!$'''" 
 
 ]]]]}]]]$$
 
 
	  	}++-- 	%**,,5&/==eDDNNPP   $"& ..
 
   	 {((('000 {&&&%g... {***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 5sm  A"C& &
D
0D?D
D
	"d, ,
e6ee(i; ;
jjn# #oo o' '
q&1pq&q&"9q!q&!q&$!w ww=x x'&x'+M!AS	 FAJ> F(AAI5 HAH HAI5 HAH.H+AI5 H-AH.H.AAI5 I4AJ> I5
AJI?AJ> JAJJAJ> JAJ JAJ> JAJ6J3AJ> J5AJ6J6AJ> J=AS	 J>
AKKAS	 K
AKKG=AS	 S	G+A[
Z6A[
[	A[
_6<A`3 `3AaaAadAd+ d+Ae	eAe	g'PAx xAx#C5BD DBD#D"BD#T!"BU U
BV%UBU0U*BV%U0BV%U=BV VBV%V BV%W,BXXBX	XBX	X-BYYBYYBYY3BZZBZZBZZ9B[[B[[B[[?B\\B\!\$B\!]B]#]#B]']*B]'c!'Bd	 d	Bd(d'Bd(n-ABo3 o3
Bp o?Bp r0Bs s
BusBs<s6Bus<But	9BuuBuuBuw Bw# w#
By w-Bxx	By xBy x9ByyBy yBy 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          |           sH	 t          | dd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 |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t-          | |d          S dS |j        dk    rddlm} 	 t          | |                                         n# t4          $ r)}t7          | t9          |          d	           Y d}~nSd}~wt          $ rC}t                              d           t7          | t9          |          d	           Y d}~nd}~ww xY wdS |j        dk    rQ	                     d           r/t9          t=                              d                               nd}n;# t>          t4          f$ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd}
                    d!          du pGt9                              d!                                                     !                                d"v }|r	 dd#l"m#} |}|s(t9          t=          tI                                          } ||          }
|
d$         }n~# t>          t4          f$ r)}	t7          | t9          |	          d	          cY d}	~	S d}	~	wt          $ r9}	t                              d%           t7          | d&|	 d	          cY d}	~	S d}	~	ww xY wtK                              d'                              d(                    \  }}tM          |||                    d)          pd                    d*          pd|
+          }t          | d,|'                                d-|j(        iz  i          S |j        d.k    ru	                     d/          }|st7          | d0          S tS          j*        |          }|st7          | d1d2	          S tS          dWi d/tW          j,                    j-        dd3         d4|j.        pd5d6z   d |j/        d'|j0        d(|j1        d-te          j3        |j(                  d7te          j3        |j4                  d8dd9dd*|j5        d)|j6        d:|j7        d;|j8        d<|j9        d=|j:        d>tw          |d>d          d?tw          |d?d          d@tw          |d@d          dAty          j<                    dBty          j<                    }tz          5  |t|          |j?        <   t}          j@        |j?                   t          t|                    t          k    r2t}          jC        dC           t          t|                    t          k    2ddd           n# 1 swxY w Y   |D                                 t          | d,|'                                d-|j(        iz  i          S # t          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w|j        dDk    r	 t          | t                              d'                              S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dEk    r                    dF          pdG                                 !                                }                    dH          }|st7          | dI          S |#t9          |                                           pd}t          ||          }|                    dJ          s$t7          | |                    ddK                    S t          | |          S |j        dLk    r                    dF          pdG                                 !                                }|st7          | dI          S t          |          }|                    dJ          s$t7          | |                    ddK                    S t          | |          S |j        dMk    rI	                     dN          }                    dO          }|t9          |                                           !                                }|dPv rt          | t          d                    S |dQv rt          | t          d                    S t7          | dR| dS          S |t          | t          |                    S t7          | dT          S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dUk    r\ddlK}ddVlmL} |M                    |           ddlNmO} |jP        |_P        |j)        |_)        |j'        |_'        t          | dJdWdX          S |j        dYk    rt          | dZ          S |j        d[k    rt          | dZ          S |j        d\k    r	 t          d/d4           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY wt          d/                   5  t9          d4                                                    dd]         pd5|_.        |D                                 ddd           n# 1 swxY w Y   t          | d,|'                                i          S |j        d^k    rk	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd_vrt7          | d`          S d/         }d_                                          }	 t          |          }n!# t          $ r t7          | d1d2          cY S w xY wdG}|rYddalUmV}  |             ddblUmW}  |            } |                     dci           }!|!                    ddi           }"t          |"t                    r||"vrt7          | de| dfd2          S |"|         }#t          |#t                    r|#                    dgdG          p|#                    dhdG          g}$|#                    di          r|$Z                    dj|#di                     |#                    dk          r|$Z                    dl|#dk                     dm[                    dn |$D                       }nt9          |#          }t          |          5  |r|nd|_:        |D                                 ddd           n# 1 swxY w Y   t          | d|j:        |do          S |j        dpk    rB	 	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd/         }                    dq          }%|%Pt          |%t                    r|%st7          | dr          S t          ds |%D                       st7          | dt          S 	 t          |          }n!# t          $ r t7          | d1d2          cY S w xY wt          |          5  |%|_^        |D                                 ddd           n# 1 swxY w Y   t          | d|j^        du          S |j        dvk    rn| j_        dwk    rt          |ja                  }&|ja        r|&                    d/dGg          d         ndG}|st7          | d0d          S 	 t          |          }n!# t          $ r t7          | d1d2          cY S w xY wtw          |dxi           pi }'t          | dy|'i          S 	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd/         }                    dz          }(                    d{          })d|}*d}}+|(t          |(t8                    sdG}(t          |(t8                    rt          |(          |*k    r
|(d|*         }(|)t          |)t                    sg })t          |)t                    rt          |)          |+k    r
|)d|+         })	 t          |          }n!# t          $ r t7          | d1d2          cY S w xY wt          |          5  tw          |dxi           pi }'|(|(|'dz<   |)|)|'d{<   |'|_b        |D                                 ddd           n# 1 swxY w Y   t          | d|jb        d~          S |j        dk    rS	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY wtw          |d dG          },	 t9          t=                              d |j/                                      }-n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wt          d/                   5  |-|_/        d'v sd(v retK                              d'|j0                  d(v r                    d(          ndtw          |d(d                    \  }}.|||_0        |.|_1        |D                                 ddd           n# 1 swxY w Y   t9          |,pdG          t9          |-pdG          k    rC	 ddlcmd}/  |/d/                    n*# t          $ r t          e                    d           Y nw xY wt          |-           t          | d,|'                                d-|j(        iz  i          S |j        dk    r                    d/dG          }|r)t          |t8                    r|                                 st7          | dd	          S |                                 }t          d |D                       st7          | dd          S 	 t          |d          }n"# t          $ r t7          | d1d2	          cY S w xY wt                              dd                    }0	 ddl"mh}1  |1||0          }t          | |          S # t4          $ r)}t7          | t9          |          d	          cY d}~S d}~wt          $ rD}t                              d|           t7          | t          |          d	          cY d}~S d}~ww xY w|j        dk    rŉ                    d/dG          }|st7          | d0          S t          d |D                       st7          | dd          S t          |          }2|2                    d          rt7          | dd          S t          |          }3t          |          }4tz          5  t}          jm        |d           ddd           n# 1 swxY w Y   	 t          jo        d           n*# t          $ r t          e                    d           Y nw xY wddlUmp}5  |5|           	 t           | dz  q                                }6|6r                    t!          jq                               n!# t          $ r t7          | dd          cY S w xY w	 |6o                    d           |6s                    d          o                    d           n+# t          $ r t          e                    d|6           Y nw xY wt          5  t          jm        |d           ddd           n# 1 swxY w Y   	 ddlcmd}/  |/|           n+# t          $ r t          e                    d|           Y nw xY w|3s>	 ddlvmw}7  |7|           n+# t          $ r t          e                    d|           Y nw xY wt          | dJdi|4          S |j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY wt          d/                   5  g |_(        g |_4        d5|_.        |D                                 ddlUmp}5  |5d/                    ddd           n# 1 swxY w Y   t          | d|'                                d          S |j        dk    r<	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w                    d          t7          | d          S 	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY wt          d                   }8t          d/                   5  |j(        d|8         |_(        |D                                 ddd           n# 1 swxY w Y   t          | d|'                                d-|j(        iz  d          S |j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wt          d/         t8                    st7          | d          S 	 t          d/                   }9n!# t          $ r t7          | d1d2          cY S w xY w                    d          }:|:N	 t          |:          }:n'# t4          t>          f$ r t7          | d          cY S w xY w|:dk     rt7          | d          S                     d4          };|;r+t9          |;                                           dd]         pd};|9j(        pg }<|:|<d|:         }=nt          |<          }=|;r|;}>n|9j.        pd5}?|? d}>tS          |9j/        |9j0        tw          |9d)d          |>|=|9j?        d          }@tz          5  |@t|          |@j?        <   t}          j@        |@j?                   t          t|                    t          k    r2t}          jC        dC           t          t|                    t          k    2ddd           n# 1 swxY w Y   |=r|@D                                 t          | |@j?        |>|9j?        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          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 ddl}m~}A  |Ad/                   }t          | dJdi|          S # t          $ r t7          | d1d2          cY S t4          $ r)}	t          | dt9          |	          i          cY d}	~	S d}	~	ww xY w|j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 ddl}m}B  |Bd/                   }t          | dJdi|          S # t          $ r t7          | d1d2          cY S t4          $ r)}	t          | dt9          |	          i          cY d}	~	S d}	~	ww xY w|j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd/         }t                              dd                    }C|Crnt          |           	 ddlm}Dm}E |E5  |Dm                    |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|Cd          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ddlm}F  |F|           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt          |           S |j        dk    rt!          |           S |j        dk    r9ddlm}G  |G            5  t'          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}G  |G            5  t)          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}G  |G            5  t+          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}G  |G            5  t-          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}G  |G            5  t/          |           cddd           S # 1 swxY w Y   |j        dk    r9ddlm}G  |G            5  t1          |           cddd           S # 1 swxY w Y   |j        dk    rt3          |           S |j        dk    rt5          |           S |j        dk    rt7          |           S |j        dk    rt9          |           S |j        dk    rt;          |           S |j        dk    rt=          |           S |j        dk    rt?          |           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tK          |           S |j        dk    rddlm}H t9                              ddG          pdG                                           }I|Ist7          | d֦          S 	 t          | d |H|I          i          S # t4          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	wt          $ r t7          | dd2          cY S t          $ r(}	t7          | t          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rtQ          |           S |j        dk    rtS          |           S |j        dk    rtU          |           S |j        dk    r                    d_dG                                           }|st7          | dݦ          S 	 ddlm}Jm}K ddlm}L |dk    r |K|            |J|d          }ddlUm}M  |M             t          | |d |L|          i          S # t4          t`          f$ r(}	t7          | t          |	          d2          cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rꉁ                    d_dG                                           }|st7          | dݦ          S ddl}N |Nj        d|          st7          | d          S                     d          }O|OBt9          |O                                           }O |Nj        d|O          st7          | d          S                     d          r(                    ddG                                           nd}P                    dH          r(                    dHdG                                           nd}|Pr%|P                    d          st7          | d          S 	 ddlm}Q  |Q||Ot                              dd                    |P|          }t          | d|d          S # t4          th          t          f$ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w|j        dk    rՉ                    d_dG                                           }|st7          | dݦ          S 	 ddlm}Rm}K  |K|            |R|          }t          | |          S # t4          t`          f$ r'}	t7          | t          |	                    cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rddlm}Sm}Tm}Um}Vm}W dv r.t9          d                   pdG                                 pdd<    |T            }X |U|           }Yt          |Yo
 |W|Y                    }Zt          t                              d          t8                    o'                    ddG                                                     }[t                              d                    }\|[s|\r9ty          j        ddG                                           rt7          | dd          S t}                    }]|]m                    dd            |T            }^t          |[o|^o|X           }_|Z}`d}a|_r|Zs |S            }ad}`|^|]d<   |`|]d<   |_|]d<   |ast          | |]          S t          j        |]dd                               d          }b|                     d           |                     dd           |                     dt9          t          |b                               |                     dd            |V| |a           t          |            |                                  | j                            |b           dS |j        dk    rddlm}T ddl}c |T            s|c                    d	          sddl}d	 | j                            d
dG                              d          d                                          }e| j                            ddG                                           }f| j        d         }g|d                    |ep|fp|g          }h|hj        p|hj        }in# t4          $ r d}iY nw xY w|ist7          | dd          S 	 t          | t                    ddi          S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rY	 t          | t                    ddi          S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w|j        dk    rddlm}T ddl}c |T            s|c                    d	          sddl}d	 | j                            d
dG                              d          d                                          }e| j                            ddG                                           }f| j        d         }g|ep|fp|g}j|d                    |j          }h|hj        p|hj        }in# t4          $ r d}iY nw xY w|ist7          | dd          S 	 t          | t                              S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	wt          $ r(}	t7          | t9          |	          d          cY d}	~	S d}	~	ww xY w|j        dk    rt          | t                                S |j        dk    rddlm}T ddl}c |T            s|c                    d	          sddl}d	 | j                            d
dG                              d          d                                          }e| j                            ddG                                           }f| j        d         }g|ep|fp|g}j|d                    |j          }h|hj        p|hj        }in# t4          $ r d}iY nw xY w|ist7          | dd          S t9          pi                     dF          pdG                                           !                                }.t9          pi                     d          pdG          }Pt9          pi                     dH          pdG                                           pd}	 t          | t          |.|P|                    S # t          $ r}	t7          | d|	 d          cY d}	~	S d}	~	ww xY w|j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY wt          d/                   5  t                              d8d                    |_        |D                                 ddd           n# 1 swxY w Y   t          | d|'                                d          S |j        dk    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wd/         }	 t          |          }n!# t          $ r t          |          }k|kst7          | d1d2          cY S |k                    d          rt7          | dd          cY S t          |k          rtS          ||k                    d4          pt          t          |          d          tI                      g |k                    d'          pd|k                    dA          |k                    dB                    }d|_        |k                    d          |_        |k                    d          p|k                    d          |_        |k                    d          |_        |k                    d          |_        |k                    d          |_        |k                    d           |_        |k                    d!          |_        |k                    d"          |_        |k                    d#          |_        |k                    d$          |_        |D                    d%           nܐt          |          }l|lst7          | d1d2          cY S t          ||k                    d4          pt          |ld          |l|k                    d'          pd|k                    d)          |k                    dA          |k                    dB          &          }d|_        |k                    d          |_        |k                    d          p|k                    d          |_        |k                    d          |_        |k                    d          |_        |k                    d          |_        |k                    d           |_        |k                    d!          |_        |k                    d"          |_        |k                    d#          |_        |k                    d$          |_        Y nw xY wt          |          5  t                              d9d                    |_        |D                    d%           ddd           n# 1 swxY w Y   t          | d|'                                dt          |                    S |j        d'k    r	 t          d/           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY w	 t          d/                   }n!# t          $ r t7          | d1d2          cY S w xY w                    d*          pdrdd(lm}m  |m            }nt          fd)t                      D             d          }o|ost7          | d*d2          S t          |o                    d)          |n          st7          | d*d2          S t          d/                   5  |_5        |D                                 ddd           n# 1 swxY w Y   t          | d|'                                d          S |j        d+k    rL	 t          d_           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wddl}Ndd(lm}m d_                                          dd,         }|st7          | d-          S                     d.          }p|pr# |Nj        d/|p          st7          | d0          S t                      }qtW          j,                    j-        dd3         ||p |m            pdty          j<                    d1}r|qZ                    |r           t          |q           t          | d|rd2          S |j        d3k    rV	 t          d*d_           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wddl}Ndd(lm}m t                      }qt          fd4|qD             d          }r|rst7          | d*d2          S  |m            }nt          |r                    d)          |n          st7          | d*d2          S d_                                          dd,         |rd_<   d.v r4d.         }p|pr# |Nj        d/|p          st7          | d0          S |p|rd.<   t          |q           t          | d|rd2          S |j        d5k    r	 t          d*           n4# t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	ww xY wdd(lm}m t                      }qt          fd6|qD             d          }r|rst7          | d*d2          S  |m            }nt          |r                    d)          |n          st7          | d*d2          S fd7|qD             }qt          |q           t          j                    r	 t          j        t          j        d8                    }s|sD ]}t|t                    d*          d*         k    rq	 t          |td/                   }d|_5        |D                                 S# t          $ r2 t          e                    d9|t                    d/                     Y w xY wn+# t          $ r t          e                    d:           Y nw xY wt          | dJdi          S |j        d;k    rt          |           S |j        d<k    rM                    d=dG          }o|od>vrt7          | d?          S dd@lm}u t          |  |u|o                    S |j        dAk    rM                    d=dG          }o|od>vrt7          | d?          S ddBlm}v t          |  |v|o                    S |j        dCk    rt          |           S |j        dDk    reddElm}wm}Sm}Vm}T ddFlm}xm}y  |T            st          | ddGdH          S | j        d         }z |x|z          st          | ddIidJ	          S                     dKdG          }{ |w|{          s |y|z           t7          | dLdM          S  |S            }||                     d           |                     ddN           |                     dd           t          |             |V| ||           |                                  | j                            t          j        dJdi                                                     dS |j        dOk    rddPlm}}m}~m}U  |U|           }|||r |~||           |                     d           |                     ddN           |                     dd           t          |             |}|            |                                  | j                            t          j        dJdi                                                     dS |j        dQk    rst7          | dR          S                     d dG          }                    dSdG          }|r|st7          | dT          S 	 ddUlm} t          |  |||                    S # t4          $ r'}	t7          | t9          |	                    cY d}	~	S d}	~	wt          $ rD}	t                              dV           t7          | t9          |	          d	          cY d}	~	S d}	~	ww xY wdS (X  z?Handle all POST routes. Returns True if handled, False for 404.POSTr  z/api/csp-reportr"   csrfr   Cross-origin request rejected  r  z/api/uploadz/api/upload/extractz/api/transcriber  z!/api/session/recovery/repair-safer   )repair_safe_session_recoveryr  cleanr     r  )handle_kanban_postFTr  r  r  Nzdashboard config save failedr  z/api/session/newr  worktree>   r+   r.   r-   r,   )create_worktree_for_workspacer   z(failed to create worktree-backed sessionzFailed to create worktree: rg  r  r-  r  )r  rg  r  r-  r  worktree_infori   r  z/api/session/duplicater   r  r  r     r  r  z (copy)r  r  r  r  r  r  personalityenabled_toolsetsr  r  r  r  r=  z/api/default-modelr  r  r*   api_keyzprovider is requiredrJ  zUnknown errorz/api/providers/deleter  displayeffort)showr.   r,   r+   )hideofffalser@  z'display must be show|hide|on|off (got 'z')z,reasoning: must supply 'display' or 'effort'z/api/admin/reload)r~  z
api.models)rx  reloadedz/api/sessions/cleanup)	zero_onlyz"/api/sessions/cleanup_zero_messagez/api/session/renamer  z/api/personality/setr   zMissing required field: namer?  r  r  rA  zPersonality "z" not found in config.yamlsystem_promptprompttonezTone: stylezStyle: r   c              3      K   | ]}||V  	d S rX   r   rY   s     r   r[   zhandle_post.<locals>.<genexpr>  s'      "9"9q"91"9"9"9"9"9"9r   )rJ  r
  r  z/api/session/toolsetstoolsetsz)toolsets must be a non-empty list or nullc              3   D   K   | ]}t          |t                    o|V  d S rX   )r   r   r   r  s     r   r[   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)rJ  r  z/api/session/draftr  composer_draftdraftr   filesiP  2   )rJ  r  z/api/session/update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   r[   zhandle_post.<locals>.<genexpr>0  (      MMA1??MMMMMMr   zInvalid session_idrn   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   r[   zhandle_post.<locals>.<genexpr>F  r)  r   r  z8Read-only imported sessions cannot be deleted from WebUI
missing_okzFailed to unlink session index)_evict_session_agent.jsonz	.json.bakz Failed to unlink session file %sz9Failed to close workspace terminal for deleted session %s)delete_cli_sessionzFailed to delete CLI session %sz/api/session/clearrJ  ri   z/api/session/truncate
keep_countz%Missing required field(s): keep_countz/api/session/branchzsession_id must be a stringzkeep_count must be an integerzkeep_count must be non-negativez (fork)fork)r  rg  r-  r  r  r  r  )r   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_lastr  r  )r4  r5  onceresolve_all)rJ  r  z/api/btwz/api/backgroundz	/api/goalz/api/chat/startr  z	/api/chatz/api/chat/steer)_handle_chat_steerz/api/terminal/startz/api/terminal/inputz/api/terminal/resizez/api/terminal/closez/api/crons/createrZ  z/api/crons/updatez/api/crons/deleter^  z/api/crons/pausez/api/crons/resumez/api/file/deletez/api/file/savez/api/file/createz/api/file/renamez/api/file/create-dirz/api/file/revealz/api/file/pathz/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/memory/writez/api/profile/switchname is required)switch_profile_validate_profile_name)build_profile_cookier7  )process_wide)invalidate_models_cachez
Set-CookierV  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 namebase_url)r  r  z,base_url must start with http:// or https://)create_profile_apiclone_config)rB  rE  rC  r  )rJ  r-  z/api/profile/delete)delete_profile_apir>  r  )create_sessionr  r  set_auth_cookier  r  r  _set_password_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  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/pinz/api/session/archivez9Read-only imported sessions cannot be archived from WebUIr
  r2  )r   r  r  r  rg  r  r  r  r   r  r  r   r   r   r   r   r   r  )r-  r  r  z/api/session/mover  c              3   4   K   | ]}|d          k    |V  dS r  Nr   )r   rZ   
target_pids     r   r[   zhandle_post.<locals>.<genexpr>  s1      MMqq*/L/L/L/L/L/LMMr   zProject not foundz/api/projects/create   r_  colorz^#[0-9a-fA-F]{3,8}$zInvalid color format)r  r   rV  r-  r  )rJ  projectz/api/projects/renamec              3   @   K   | ]}|d          d          k    |V  dS rS  r   r   rZ   r   s     r   r[   zhandle_post.<locals>.<genexpr>6  6      JJ1AlOtL7I$I$IQ$I$I$I$IJJr   z/api/projects/deletec              3   @   K   | ]}|d          d          k    |V  dS rS  r   rY  s     r   r[   zhandle_post.<locals>.<genexpr>O  rZ  r   c                 8    g | ]}|d          d          k    |S )r  r   rY  s     r   r^   zhandle_post.<locals>.<listcomp>W  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/applyrc  )rH  r  z!target must be "webui" or "agent")apply_updatez/api/updates/force)apply_force_updatez/api/session/import_cliz/api/auth/login)verify_passwordrG  rH  r  )_check_login_rate_record_login_attemptzAuth not enabled)rJ  r   z)Too many attempts. Try again in a minute.i  passwordrn    application/jsonz/api/auth/logout)clear_auth_cookieinvalidate_sessionr  z/api/rollback/restorezrequest body is requiredry  z%workspace and checkpoint are required)restore_checkpointzrollback/restore failedr   )r  r  r   rr   r  rT  r  r/  r  r  r  r   r  r=   r  r  r  r
  r0   r   r  r  r  rx  r  save_dashboard_configrJ   r  r   r  r  r\  r   r   r  r  r  r  r  r  r  r  r  r`  ra  rb  r  r  rg  r  r  r  r  r  r-  r  r  r  r
  rh   r  r  r  r   move_to_endrQ   r  popitemr  r  rt  r&  r'  r  r  	importlibr~  reload
api.routesroutesrp   _handle_sessions_cleanupr  rq   r  r  r@  r  r   r  r   rp  rc  r  r  r;  r   r/   r  api.terminalr#  rs   r  r  r*  r  r  r  rt   r  r	  unlinkr.  rG   rH   r   r  r  r  r0  rJ  _handle_session_compress_start_handle_session_compress_handle_conversation_rounds_handle_handoff_summaryr  r4  r5  r8  tools.approvalr4  r5  r7  r9  _handle_btw_handle_background_handle_goal_command_handle_chat_start_handle_chat_syncapi.streamingr9  _handle_terminal_start_handle_terminal_input_handle_terminal_resize_handle_terminal_closer<   r[  _handle_cron_create_handle_cron_update_handle_cron_delete_handle_cron_run_handle_cron_pause_handle_cron_resume_handle_file_delete_handle_file_save_handle_file_create_handle_file_rename_handle_create_dir_handle_file_reveal_handle_file_path_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_memory_writer=  r>  api.helpersr?  rA  FileNotFoundErrorr  r%  rD  FileExistsErrorrF  r  rG  r  r  rH  r  r?   r@   r  r   dumpsr  rA  rB  r  rC  r  r  	ipaddressr#  r   r1  
ip_addressis_loopback
is_privater.  r,  r(  r*  r+  r  r  r  r  r  r  r   r  r  r   r   r   r   r   r   r  r  rk   r  nextr  r&   r  r]   r   r   _handle_session_importr~  r]  r^  _handle_session_import_clir_  r`  ra  re  rf  r  rg  )r  r  r  r  r   r  r  rS  r  r   r  worktree_requestedr  base_workspacerg  r  r   rl   ri   copied_sessionr_  r  r  r  flagrk  _models_routesr   r  _reload_cfg2	_get_cfg2_cfg2r  r  r   rP   r  r/   r  r   r   _MAX_DRAFT_TEXT_MAX_DRAFT_FILESold_wsnew_wsr  r#  r  r*  cli_meta_for_deleter  re   r.  rZ   r0  keepr  r2  custom_titlesource_messagesforked_messagesbranch_titlesource_titlerO  r4  r5  r  _p_lr9  r[  r:  r;  r=  r>  r?  rA  r$  rB  rC  rD  rF  rG  r  r  rH  r  auth_enabled_beforecurrent_cookielogged_in_beforerequested_passwordrequested_clear_passwordsavedauth_enabled_afterrK  logged_in_after
new_cookieresponse_body_osr  _xff_xri_rawaddris_local_ip_strr  r  r  r/  rc  rV  r  projr  r}  r]  r^  r_  r`  ra  	client_iprb  
cookie_valre  rf  ry  rg  r   rT  s                                                                                                                                    @@r   handle_postr    sT   )&&+fMMMD{''' 	%JJ|$$$	%g.. t   

6w 	Ww(GHQTUUU t  {m##W%%%{+++$W---{''' )))  

;!!    	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%&&!
 !
~ )HHY''/4xx--5'
 
 
 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,,,,,,,,	- {&&&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.//AA 	: 	: 	:w 3S99999	:$T,%788 	 	$w-((..00"5CAGFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 9aiikk2333{,,,	(D,'''' 	( 	( 	(wA''''''''	(w >???< F|!!##	:C  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FFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 0@AABBB{+++	(D,'''' 	( 	( 	(wA''''''''	(	:D.//AA 	: 	: 	:w 3S99999	:K,,	(2488K3U3UVVWWFF 	( 	( 	(wA''''''''	($T,%788 	 	 AK$"2d":":"CHHWag..2Bd2J2JDHH-...PTA/66# #x
 $#AG#+ FFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 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###	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$	;%66666 	; 	; 	;LL9:::::	; 	433333S!!!	;#}}},5577AMM+-//0000 	; 	; 	;w 4c:::::	;	@HHH%%%MM+&&--->>>> 	@ 	@ 	@LL;Q?????	@ & 	/ 	/#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4;):;<<<{***	(D,'''' 	( 	( 	(wA''''''''	(	:D.//AA 	: 	: 	:w 3S99999	:$T,%788 	5 	5AJAL AGFFHHH777777  l!3444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 !))++>>???{---	(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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 !//R!-kzk:OO"?33O  	4'LL!<5:L*333L &,FIt44$$/!
 
 
  	- 	-*0HV&' !2333h--,.. e,,,, h--,..	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-  	KKMMM +!!'!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{((("7D111{,,,!'4000{((("7D111{&&& $/// {+++$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 {+++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 	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
 
 $(1B(C(C#D#D   	!9 	y0"55;;== b	   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.//AA 	: 	: 	:w 3S99999	:$T,%788 	 	DHHXt4455AHFFHHH	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 !))++>>??? {,,,	(D,'''' 	( 	( 	(wA''''''''	(< 5	6C  AA 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***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ !))++__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	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 !))++>>??? {,,,	(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 {///)'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#^%%
c"""N,>???OZ888'""",,,DJd|44;;==>>>t{(((PPPPPPPPPP!\'**
 	+z***c"""N,>???OZ888'"""'"""DJd|44;;==>>>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 5sB  A- -B0C C4E- -"F #I$ $
K".JK"9KK"4AL; ;M3M.(M3.M3AP   R1QRR".RRR&^ 8'^  D ^  A8]8^ ]^ ]A^ 
_^=7_=_/` 
a"`-'a"-a":aa"a"A?k1  k1 .k1 k1 !k1 1
m;lmm*mmmp 
qq;qq
q   q>=q>As--s14s1)t: :
u+u& u+&u+%v5 5ww }//}36}3!~2 2
#<##AAA& A&ABBABBAB>B>ACCACEAE EAE4E3AE4FAF. F.
AGF8AGGAGGAGJ/AJ? J?AKKAKK/=AL8L8AL<L?AL<M(AM9 M9
AN*NAN%NAN*N%AN*N.AO OAO"O!AO"O75AP- P-
AQP7AQQAQQAQQ6B	ATTATTATT;AU U$AU:U9AU:YAY* Y*AZ	ZAZ	Z0"A[ [
A][A\[;A]\A]\9A]]A]]A]`A`/`/A`3`6A`3`;Aa a$Aa8a7Aa8bAAc cAc1c0Ac1c5?Ad5 d5%AeeAee'Af	f	AffAffAf' f'%AggAggAg' g'%AhhAhh3Ai i
Ai5iAi0i*Ai5i0Ai5i9Aj jAj-j,Aj-kAAllAllAlmAm  m 
Anm*AnnAnnAnn:Ao oAo.o-Ao.p)AqqAqqAqrAr( r(
Asr2AssAssAstAt tAt<t;At<uAu' u'!Avv
AvyA8A{{A{!{$A{!~A~% ~%
A~/AAA*B@ @BA@"	BA@+BAA	BAABAA#BA4 A4
BB%A>BB BBB%B BB%B)*BC CBD#C1	BD#C:BDDBD#DBD#D3BE E
BE5EBE0E*BE5E0BE5F6
BG/ G BG#GBG/ G#BG'G'BG/ G*BG'G+BG/ G/
BG<G;BG<M,BN
N
BNNBNN0BOOBOOBOO4BPPBPPBPP8BQQBQQBQQ<BRRBRR!BRS BSSBS"S%BS"Z0B[ [
B]	[B[8[2B]	[8B]	\	B]	\!B]\>B]	]B]	_'ABa  a Bb*aBa5a/Bb*a5Bb*bBb%bBb*b%Bb*hA	Bi! i!Bj i9BjjBj jBj k)-Bl lBn l)BmmBn mBn mBm;m5Bn m;Bn yB*B|
 |
B||B||1#B} }
B~6}B~};B~6~B~6~B~1~+B~6~1B~6#B* *
C@4C@@C@@C@AB,CD DCDDCDD/CE E
CF.ECE9E3CF.E9CF.FCF)F#CF.F)CF.HB,CK KCKKCKNCN5 N5
CON?COOCOOCOO/CP  P 
CP1P
CP,P&CP1P,CP1P5CQ QCQ)Q(CQ)R=CS
S
CSSCSTCT T
CU
T#CUT?CU
UCU
UCU' U'-CfV'CfV?H
Cf_F7CffCffA Cg#g#Cg'g*Cg'h1Ci i
Ci3iCi.i(Ci3i.Ci3i7Cj jCj+j*Cj+m"Cn
n
CnnCnoCo o
Cp
o#Cpo?Cp
pCp
t!Ct3 t3
Cu$t=CuuCu$uCu$zCz z
C{zC{z;C{{C{~ADA 0D@@DA @9D@?@<DA @>D@?@?DA A%DA,A+DA,P' DQ Q
DSQDQ4Q.DSQ4DSR9DS R:DSS DSc                     t          |           st          | ddid          S t          |           }|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   r   r  r  r  r   )handle_kanban_patchFPATCHT)r/  r  r  r   r   r  r  r  )r  r  r   r  r   s        r   handle_patchr    s    w R7$CDSQQQQWD{n-- 999999$$Wfd;;U??+GVWEEEt5r   c                     t          |           st          | ddid          S t          |           }|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   r   r  r  r  r   )handle_kanban_deleteFDELETET)r/  r  r  r   r   r  r  r  )r  r  r   r  r   s        r   handle_deleter    s    w R7$CDSQQQQWD{n-- ::::::%%gvt<<U??+GVXFFFt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  c                    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|}|                     d
           |                     d|           |                     dd           |                                }|                     dt)          t          |                               |                                  | j                            |           dS )Nr  r  r   r  r  r  rq  r  z; charset=utf-8r   r  r  r  r?  T)r   r  r   rG   r   rQ   rH   rJ   r  r]   r  suffixr   _STATIC_MIMEr0   r&  _TEXT_MIME_TYPESrA  rB  r  r   rC  r  r  )	r  r  r  r  static_fileextct	ct_headerr3   s	            r   r|  r|    s   >>(/(:CCEEK
+c*oo''
(C$--//K>,,,, > > >7K0======> >{':':'<'< >7K0====


"
"
$
$C			#**S//<	8	8B*,0@*@*@2&&&&bI#	222444

 
 
"
"C(#c#hh--888M4s   (A> >BB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 )Nr   r*   r   r  r  r  FrL  rM  r   r  rP  Content-Dispositionzattachment; filename="hermes-z.json"r?  r   r  r  T)r   r/   r0   r  rp   rq   r  __dict__r   r  rA  rB  r   rQ   r  rC  r  r  )r  r  rl   r   r  rj   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                 8   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 ]}|                    d          pd}t          |t                    rd                    d |D                       }|t          |                                          v rht          |d
          }t          |                    d          t                    rt          |d                   |d<   |	                    |            nِ# t"          t$          f$ r Y w xY wt          | |	|t'          |	          d          S )NrL  r*   r   r   r+   depth5r  r   )
match_typer   r  c              3      K   | ]H}t          |t                    r1|                    d           dk    0|                    dd          V  IdS )rN  r   r*   Nr   r  r0   rY   s     r   r[   z*_handle_sessions_search.<locals>.<genexpr>D  se       % % !)!T22% 89uuV}}7N7N EE&"--7N7N7N7N% %r   )r   r/   r   )r   r/   r0   r   r   rJ  r  r  r   r   r  r   r  rp   r  rc  rp  rq   r=   rQ   )r  r  r2   rL  content_searchr  safe_sessionsr   r  r  title_matchr  r  r(  r(  s                  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i((.BA!!T** HH % %%&% % %  
 CFFLLNN**#A)<<<%dhhw&7&7== H,8g,G,GDMt,,, + i(   %	( W7QWNNOOOs   DK!!K65K6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	 t          | t          t          |          |                    dd	g          d                   |                    dd	g          d         d
          S # t          t          f$ r(}t          | t          |          d          cY d }~S d }~ww xY w)Nr   r*   r   r  r  r  r  r   rq  )entriesr   )r   r/   r0   r  rp   r  rq   r  r=   r  r  r   r  rJ   r  )	r  r  r2   rl   r   r  r  csr   s	            r   r  r  T  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#DOORVVFSE5J5J15MNNvu--a0 
 
 	
 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 E=E82E=8E=c                 $   t          |j                                      ddg          d         }t          j        |          }|t	          | ddi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!          | ||           |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 )Nr  r*   r   r   zstream not foundr  r  	subscriber   r   text/event-stream; charset=utf-8r  no-cacheX-Accel-Bufferingno
Connection
keep-aliveTre  s   : heartbeat

)
stream_endr   cancelunsubscribe)r   r/   r0   r  r  r  r  rA  rB  rC  _SSE_HEARTBEAT_INTERVAL_SECONDSrh  rm  r  r  r  r!  _CLIENT_DISCONNECT_ERRORSr
  r=   )r  r  r  stream
subscribereventr   s          r   r  r  u  s   &&**;==a@I[##F~7$67DDDD'.v{'C'CO!!###J#(JKKK444+T222l333		(nn5TnUUtt;   ##$6777##%%% %&&&999		 $    V##(F(F#"":....    V##(F(F#"":....    $#
 4s   F D# "F #AE(%F 'E((F G 
FG FG (F> >
G
GH%G;:H;
HHHH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 )Nr   r*   r  r  r  )r   r0   r   rJ   rp   rq   r  rh   )body_or_queryrl   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rowsr,  colsr  restart)r  r  r  T)rJ  r   r  rt  r  r  r  )r  rp  r  rJ  r0   r  r  r  rn  rq   r  r   rJ   r=   r  )r  r   rl   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)Nr   r   r*   i    zinput too largei  r   )write_terminalrJ  Tr  r  r  )r  r   r0   rQ   r  rp  r  r  rq   rJ   r=   r  )r  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)Nr   r   )resize_terminalr  r,  r  r  )r  r  rJ  Tr  r  r  )r  rp  r  rJ  r0   r  rq   r  r   rJ   r=   r  )r  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)Nr   r   r"  T)rJ  closedr  )r  rp  r#  r  rJ   r  r   )r  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 )Nr   r*   r   r  )get_terminalr   zterminal not runningr  r  r   r  r  r  r  r  r  r  r  Tre  s   : terminal heartbeat

terminal_closed	exit_code)r!  terminal_error)r   r/   r0   r  rp  r   r  rA  rB  rC  r  r  rh  rm  r  r  r  r  is_setr  r!  procpollBrokenPipeErrorConnectionResetErrorConnectionAbortedError)r  r  r2   rl   r   r  r  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l333	"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 )Nr  Frn  _threadi0u  )r  fallback_poll_msrJ  watcher_runningagent sessions not enabledr   r  watcher not startedr  r   )r  r0   r  callablerh   rn  )r  watcherr  watcher_alive_trj   s         r   _gateway_sse_probe_payloadr4    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prober*   >   r+   r-   r,   r  r  r   r.  r  r-  r/  r  r   r  r  r  r  r  r  r  r  )r  sessions_changedr   Tre     : keepalive

NrN  )r  api.gateway_watcherr6  r   r/   r0   r   r4  r  rA  rB  rC  r  r  r  r!  r  rh  rm  r  r  r  r  r
  )r  r  r  r6  r1  r7  rj   rx  _probe_body_probe_statusrL  r  initial
event_datas                 r   r  r  +  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l333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'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r*   r   c              3   `   K   | ])}d t          |          cxk    rdk     r	n n|dvr|ndV  *dS        >   r  \r   Nordr   chs     r   r[   z-_content_disposition_value.<locals>.<genexpr>h  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 rC  rG  rI  s     r   r[   z-_content_disposition_value.<locals>.<genexpr>n  sk       
 
 B%%%%#%%%%%"K*?*?BBS
 
 
 
 
 
r   downloadr  z; filename="z"; filename*=UTF-8'')	r}  parser   r   rr  rp  r   r  r  )r?  r  _up	safe_nameascii_fallbackr  ascii_suffixquoted_names           r   _content_disposition_valuerS  c  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  rp  r*   r   )r   r   r   rJ  r]  r  rJ   )rT  rU  specstart_send_s
suffix_lenrl  r  s           r   _parse_range_headerr[  z  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csprc  mimecache_controlr]  c          	      L   	 |                                 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          rk|i|                     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.zPermission deniedr  zCould not stat filer  Ranger*   Ni  zContent-Rangezbytes */zAccept-RangesrH  Tr   r      r   r  r?  zbytes rp  r   r  r  zContent-Security-PolicyzX-Content-Type-OptionsnosniffzReferrer-Policyzsame-originzPermissions-PolicyzDcamera=(), microphone=(self), geolocation=(), clipboard-write=(self)r  i   )r   r  r   r  r=   r[  r#  r0   rA  rB  r  rC  r]  r   rS  r   r  r  rM  r  r  r  rQ   )r  rc  r^  r?  r_  r]  rU  
byte_rangerl  r  content_lengthf	remainingchunks                 r   _serve_file_bytesri    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'"""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8L A.L;L LL LL 
L! L!c           	         ddl ddlm}m}m} t          j                            d                    }t                              dt          |dz                                                                } |            rs ||           }|r ||          s[| 
                    d           |                     dd	           |                                  | j                            d
           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tA          | ddid          S j!        "                                }tG          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}tI          | ||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   Nr  ~r:   r;   rc  r  rd  s#   {"error":"Authentication required"}r   r*   zpath parameter requiredr  zInvalid pathz/tmp)r  MEDIA_ALLOWED_ROOTSc              3      K   | ]_}|                                 j                            t                    t          |          g          t          |          k    V  `d S rX   )r]   r   
commonpathr   )r   r  r  rc  s     r   r[   z _handle_media.<locals>.<genexpr>  sq        ;;==S[[#d))455TB     r   zPath not in allowed locationr  r   r  r  r  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  inliner+   r  
attachmentsandbox allow-scriptszprivate, max-age=3600r\  )%r?   r  r  r  r  r   r   rB   r@   r   rA  rB  rC  r  r  r   r/   r0   r   r  rG   r=   r  r  r   r   r  r   pathsepr   r]   r  r  r  r   r  ri  )r  r  r  r  r  _HOME_HERMES_HOMEr  r2   raw_pathallowed_rootsr  wsextra_rootsr  rpwithin_allowedr  r^  _INLINE_IMAGE_TYPES_INLINE_PREVIEW_TYPES_DOWNLOAD_TYPESinline_previewhtml_inline_okr?  r]  r  rc  s                             @@r   r  r    s    FFFFFFFFFF$$S))**E

=#ei6G2H2HIIJJUUWWL  \'"" 	~~b)) 	!!#&&&0BCCC!!!M FGGG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   !E3 3FF AH9 9
II+A
K66
LL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          |j                  |          }|	                                r|
                                s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 }t          | ||	|d|          S )Nr   r*   r   r  r  r  r   rL  r+   r   r  r  ro  r~  >   application/xhtml+xmlr  r  r  r  r  r  r\  )r   r/   r0   r  rp   rq   r  r   r  r]   r  r  r  r   r  ri  )r  r  r2   rl   r   r  force_downloadrc  r  r^  r  dangerous_typesr  r?  r]  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$q{++S11F==?? >&.."2"2 >7K0====
-



C<788D
 VVHrd++A.#5NMMMO#;(;N"0rT_5L5LUc5L,,jrK &4
=
!
!C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)	Nr   r*   r   r  r  r  r   path is required)r   r/   r0   r  rp   rq   r  r  r   r  r  rJ   r  )r  r  r2   rl   r   r  r   s          r   r  r  c  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 )Nr   r*   r   r   rU  )
r   r/   r0   r5  r4  r   rc  rQ   r  r  )r  r  rl   rh  rZ   rS  s         r   r  r  u  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.
    r   r*   r   r  rK  ra  Nr   r   r  r  r  r  r  r  r  r  r!  r=  rU  Tre  r9  r]  )r   r/   r0   r  rh  rj  r5  rI  r/  r   r4  r   rc  r  rQ   rA  rB  rC  r|  r!  r  rm  r  r  r  r  rQ  )	r  r  rl   rL  initial_pendinginitial_countq_listr!  rj   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l333"""""" 	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.r   r*   r   pattern_keytest_patternr;  zrm -rf /tmp/testztest pattern)r;  r  pattern_keysr   TrJ  r   r   r  r  r  )r   r/   r0   r/  r  )r  r  r2   rl   r   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 )Nr   r*   r   rV  )r   r/   r0   get_clarify_pendingr  )r  r  rl   rV  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 availabler   r*   r   r  )r5  _clarify_sse_subscribers_gateway_queuesr4  rK  ra  r   r   r  r  r  r  r  r  r  r  r  r=  rU  Tre  r9  clarify)clarify_sse_subscriber  r   r/   r0   api.clarifyr5  r  r  r4  rh  rj  r/  r   r  r   rQ   rA  rB  rC  r|  r!  r  rm  r  r  r  r  clarify_sse_unsubscribe)r  r  rl   _clarify_lock_clarify_subs_clarify_gateway_queues_clarify_pendingrL  r  r  gw_q_legacyr!  rj   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l333"""""" 	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.r   r*   r   questionzWhich option?choicesr  )r  choices_offeredr   kindTr  r   r  r  r  )r   r/   r0   submit_clarify_pendingr  )r  r  r2   rl   r  r  s         r   r  r  (  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  r*   r   r  rg  no_provider)r   r~  )_resolve_provider_aliasNrj   c                 D    t          |            t          |           S rX   )r  r  )rj   	cache_keyr  s    r   _finishz$_handle_live_models.<locals>._finishg  s#    #Iw777Wg&&&r   ..r;   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)NrW  custom:r   )_custom_provider_slug_from_namer  r   r*   )	r   r  r  r0   r   rc  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   rg  r*   r~  r?  r   )r0   r   r  r   rc  )r  r  r  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 )	Nr  z${}rO   rL  r  r*   key_env)r0   r   r   r   r  rQ   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   rW  r  rC  r  r   z/v1z/modelsz
/v1/modelsAuthorizationzBearer )r#     re  r   c                 d    g | ]-}|                     d           |                     d d          .S r?  r*   r   r   r(  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  r  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   r  s     r   r^   z'_handle_live_models.<locals>.<listcomp>  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   r  s     r   r^   z'_handle_live_models.<locals>.<listcomp>  s    :::q1T7:::r   )r  r~  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   r  rp  r  GPT)
r  r  gemmallamamistralqwenr  grokkimiglmNr   r  )r  GLMrj  AIXLMoE)r   r   r   
capitalizer  rp  rr  r  )
midr  rP   r   rZ   plrp  orig_fmt_ollamar  s
           r   _make_labelz(_handle_live_models.<locals>._make_label3  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?  rp  r   )r   r  r  s     r   r^   z'_handle_live_models.<locals>.<listcomp>L  s0    SSSsSS;;s+;+;<<SSSr   z%_handle_live_models failed for %s: %s)-r   r/   r0   r   r   r  r  r  r  r  r  r  r  r?   r   rp  r  abspathr  normpathinserthermes_cli.modelsr  r=   rr   rs   r   r`   urllib.requestr   r%  r  requestRequesturlopenr   rM  r   rc  rQ   _OPENAI_COMPAT_ENDPOINTSr  r  r  r   )-r  r  r2   _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_resp_body_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                    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 ]j}	 |                                }|	                    |j        |j        |j        d           @# t,          $ r t.                              d|           Y gw 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_DIRNr
  r*   r   job_id requiredr  r  ![A-Za-z0-9_-][A-Za-z0-9_.-]{0,63}rq  r  invalid job_idoffsetr@  r   r  r"  50z!offset and limit must be integersr   c                 4    |                                  j        S rX   r   r   rf  s    r   r  z&_handle_cron_history.<locals>.<lambda>t  s    qvvxx?P r   Tr  )r  sizemodifiedz"Failed to stat cron output file %s)r
  rt  rS  r  )r  r  r  r   r/   r0   r  	fullmatchr]  rJ  r  rJ   r\  r]   r   globrQ   r   r   r   r  r   rI   rr   rs   )r  r  CRON_OUTr$  r2   r
  r  r"  out_dirrt  rS  	all_filespagerf  r  s                  r   r  r  U  sz    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 !J "     
  F F FA1EEEEEFWQWXXYYYs%   <A>C; ;%D#"D#
<G%G/.G/c                    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          | ||||	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   r  Nr
  r*   r  r   zjob_id and filename requiredr  r  r  r  r  zinvalid filenamezrun not foundr  r   rr  r  )r
  r  r   snippetr  )r  r  r  r   r/   r0   r  r&  rG   is_relative_tor]   r   _cron_output_snippetr=   r   )r  r  r(  r$  r2   r
  r  fpathr   r-  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//V&-'C C D D 	D 9 9 97CFF+C8888888889s   :E 
F F=FF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   r  r  r  r   r   Nz(empty))r   	enumerater   rp  r   )r   r"  r  r'  r%  r   r   s          r   r/  r/    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   r  r
  r*   r"  r  r   r  r  r  r   c                 4    |                                  j        S rX   r"  r#  s    r   r  z%_handle_cron_output.<locals>.<lambda>  s    16688;L r   Tr  r   rr  r  )r  r   z"Failed to read cron output file %s)r
  outputs)r  r  r   r/   r0   rJ  r  r]   r   r'  r   r   r   r*  r=   rr   rs   )r  r  r(  r2   r
  r"  r)  r5  r   rf  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.r
  r*   r   r   )r
  rt  elapsedc                 ^    i | ]*\  }}|t          t          j                    |z
  d           +S )r   )rC  r  )r   jidr  s      r   r#  z'_handle_cron_status.<locals>.<dictcomp>  s2    ___&#qsE$)++/155___r   Nrt  )	r   r/   r0   r  r  rC  r  r   rB  )r  r  r2   r
  rt  r8  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@  rX  Tr\  last_run_atr  r  r?  r*   r   Unknownlast_statusr2  r.  F)r
  r   rx  completed_atr.  )completionsr=  )r  r   r/   r[  r0   r  rY  r   r   fromisoformatrr  r  rJ   r\  r   r  ImportError)r  r  r  r2   r=  rY  r3  rB  r+  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  }|                                r|                    dd	          nd
}|                                r|                    dd	          nd
}t          | t          |          t          |          t          |          t          |          |                                r|
                                j        nd |                                r|
                                j        nd d          S )Nr   r6   memoriesr;   	MEMORY.mdUSER.mdr   rr  r  r*   )memoryusermemory_path	user_pathmemory_mtime
user_mtime)r<   r7   rD  r   rA   r]   r   r  r  r   r   r   )r  r7   mem_dirmem_file	user_filerJ  rK  s          r   r  r     sq   7777777((**Z7 7 7 7)++	)J67$H)#I ??	GI>>>  		WY??? 	
 "6** &&x==Y8@8I8ISHMMOO44t7@7G7G7I7IS)..**33t	
 	

 
 
s    #<<Fc                    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   z*.jsonr   r  Tr,  r   z"Failed to clean up session file %s)rJ  cleaned)r  r'  r   r   r  r  r   rQ   r  r  r  r  r  rq  r=   rr   rs   r	  r]   r  )r  r   r  rT  rZ   r   should_deletes          r   ro  ro  #  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.
    r   r  Nr  r  zquestion is requiredr  r   $session already has an active streamr  r  r   r  r  r-  r  rg  r  r-  zbtw: r$   )	track_btwT)	ephemeralr  rc  rd  kwargsdaemon)r  r   r  )r  rJ   r  r   rp   rq   r   rh   r  r  r  r  r  r  r  rg  rc  r  r  r  r`  ra  rb  r  r  rZ  r   	threadingThreadr"  rl  )r  r   r   r   r  current_stream_id_new_sessionr  r[  r  r  rZ  thrs                r   rw  rw  :  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.
    r   r  Nr  r  zprompt is requiredr   rX  r  r-  rY  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)r  r   )r  r*   r  	assistantr  r   z(no answer produced)z(background task failed)r/  Tr,  )r"  rg  r  r  r  r  reversedr  r   r  r0   r   r   r=   r  rq  )_Sessionr  _answer_m_contentbg_sidrf  r  
parent_sidr  r   r  task_ids        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/T)rc  r^  )rp  r  r   )r  rJ   r  r   rp   rq   r   r  r  rh   r  rg  r  r  r`  ra  rb  r  r  r  r  r  re  rf  r   r_  r`  rl  r  )r  r   r   rb  bgr  re  rq  rc  rn  rf  r  ro  r  r   r  rp  s            @@@@@@@@r   rx  rx  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  r  r  rK  r  r   r*   r  r   r   r  attachments)rc  rh   r   r  r0   rp  r   r   rJ  r[  r  r   )	r   r  ru  r  existingr   latest_textmsg_textuser_msgs	            r   /_checkpoint_user_message_for_eager_session_saverz    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   )r  r  r  c                   || _         || _        || _        || _        || _        || _        ||nt          j                    | _        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.
    Neager)r  rg  r  r  r  r  r  r  r  rz  r  )r   r  ru  r  rg  r  r  r  s           r   &_prepare_chat_start_session_for_streamr}    s    ( AKAG%A"A A'A)3)?::TY[[A"$$//7 		
 	
 	
 FFHHHHHr   )ru  r  normalized_modelr  goal_relatedr~  r  c                   |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          | ||||||           ddd           n# 1 swxY w Y   |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 t-          j        t0          | j        |||||f||dd
          }|                                 || j        | j        |                    d          d}|r||d<   |r||d<   |S )zHPersist pending state, register an SSE channel, and start an agent turn.active_stream_checkNr  active_stream_lock_waitr6  rW  r  )r   r  _statusstale_stream_cleanupTsession_lock_waitsave_pending_state)r  ru  r  rg  r  r  turn_journal_submittedr   )append_turn_journal_event	submittedrK  )	r  r  r  r   ru  r  rg  r  r  z-Failed to append submitted turn journal eventr   r  stream_registrationworker_thread_start)r  r  r\  turn_id)r  r   r  r  r  effective_model_provider)r  rh   r  r  r  r   r  discardr`  ra  rb  r  r}  api.turn_journalr  r  r=   rr   rA  r  r  r  r_  r`  r"  rl  r0   )r   r  ru  r  rg  r  r~  r  r  ra  current_activer  session_lockjournal_eventr  r  rc  r)  s                     r   _start_chat_stream_for_sessionr    st    #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.#)	
 	
 	
 	


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 -1: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+-0E))E-0E-&F7 7&G G 9III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        |
          } ||j        |||
          }|                    dd          s/|                    d          dk    rdnd}t?          | ||           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;          ||          \  }}}tA          ||g ||||d"          }tC          |"                    d#d$          pd$          }|#                    |           |dk    r* ||j        ||
           d|d<   t?          | ||           S t?          | |          S )%z@Handle WebUI /goal command controls and optional kickoff stream.r   Nr  r  r-  r*   r   _PROFILE_ID_REr7  invalid profiler  r  context_messagesr  r  F)r>  )goal_command_payloadgoal_state_snapshotrestore_goal_staterd  r   )rx  pauseresumer  stopdoner  rg  r  )r  )stream_runningr  rJ  Tr   agent_runningr  r  kickoff_prompt)r  ru  r  rg  r  r~  r  r  r   )$r  rJ   r  r   rp   rq   r0   r   r<   r  r&  rD  r&   rh   r  r-  r  r  r  r>  r=   	api.goalsr  r  r  r   r  r  rg  r  r   r  r  rJ  r  r  )r  r   r   r   requested_profiler  has_persisted_turnsra  r  r>  r  r  r  r  	goal_argsgoal_actionwill_kickoffr  rg  r  r~  previous_goal_staterequested_modelr  rj   rx  r  stream_responses                               r   ry  ry  t  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""	%!	  G ;;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<81C+ +C:9C:
FF F6 G G&%G&	6K   
K1
K,&K1,K156P, ,
Q6QQQ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+          ||          \  }}}t-          |||	|
||||          }t/          |                    dd          pd          }|r|                     d          nd  t3          | ||           |r|                                 S S # |r|                                 w w xY w)!Nvalidate_session_idr   rp   r  r  validate_profiler-  r*   r   r  r7  r  r  r  r  r  normalize_messager   zmessage is requirednormalize_attachmentsru  r   resolve_workspacer  rg  r  resolve_model_provider)r  ru  r  rg  r  r~  r  r  r   r6  r  )r  r  rJ   r  r   r  rp   rq   r0   r   r<   r  r&  rD  r&   rh   r  r-  _normalize_chat_attachments%_resolve_chat_workspace_with_recoveryrg  r  r  rJ  r  r  )r  r   r  r   r   r  r  r  r  ru  r  r  r  rg  r  r~  r)  rx  s                     r   rz  rz    s   F-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'''''''4  	KKMMMM	7	(((7++6qw  4'' HH%&&&,d33 	
 15>

+,,,$2Y3
 3
/~/ 2#)-	
 	
 	
 X\\)S118S99(,6

#$$$$(6222 	KKMMMM	4 	KKMMMM	s   P. - P. 
A5A0A5P. 0A55P. B( 'P. (CP. CAP. 21E< ;P. <FP. 
FCP. /AP. #K2 1P. 2
L:<L5L:P. 5L::CP. .Q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)rh   r   r  rJ   r  r  r  r=   )r   requested_workspaceexplicitrE   fallbacks        r   r  r  7  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  r*   r   r^  )r   r   r^  r$  is_image)	r   rc  r  r   r0   r   rJ  r  r   )
raw_attachmentsrZ  r  r   r   r^  attr$  r  r   s
             r   r  r  I  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                 d   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'}  |t          |j                            }d"|j         d#} tQ          |j)        pg           }!tQ           ||                    }"|*                    ||z   |  ||"          |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|"}$ ||"|$          }%|%|_,         ||!|" ||!|$          |          |_)        |j-        d&k    rt]          |j)        |j-                  |_-        |/                                 d	d	d	           n# 1 swxY w Y   	 ta                                          d'          rLdd(l1m2}&  |&|j
        |j3        pd|j4        pd|j5        |j        |j-        tm          |j)                  )           n*# t<          $ r tn          8                    d*           Y nw xY wt	          | |#                    d+          pd|#                    d,d          rd-nd.|9                                d%|j)        iz  d/ |#:                                D             d0          S )1zJFallback synchronous chat endpoint (POST /api/chat). Not used by frontend.r   r   r*   r   zempty messager  r  r  Nrg  r  rL  r   )	_ENV_LOCKTERMINAL_CWDHERMES_EXEC_ASKHERMES_SESSION_KEYr+   )AIAgent)r  "resolve_custom_provider_connection0resolve_runtime_provider_with_anthropic_env_lock)resolve_runtime_provider	requestedr  r  rC  z2[webui] WARNING: resolve_runtime_provider failed: T)r  r  rH  rg  r  rC  r  r   
quiet_moder  r   )*_merge_display_messages_after_agent_result_restore_reasoning_metadata_sanitize_messages_for_api_session_context_messages_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.)user_messagesystem_messageconversation_historyrp  persist_user_messager  r  sync_to_insights)sync_session_usage)r   r  r  r  rg  r  r  z&Failed to update session cost trackingr  	completedr  partialc                 &    i | ]\  }}|d k    ||S )r  r   )r   r>  vs      r   r#  z%_handle_chat_sync.<locals>.<dictcomp>  s#    JJJ1!z//q!///r   )answerrx  ri   r   );rp   r   r0   r   r  r  r  rJ   r  r  r   r  rg  rh   r  r|  r  r?   r  	run_agentr  r  r  r  r  r  	api.oauthr  hermes_cli.runtime_providerr  r=   r  r   r   r  r  r  r  r  r  rc  r  run_conversationr  r  r  r  r  r  api.state_syncr  r  r  r  rQ   rr   rs   r  rB  )'r  r   r   r  r  r   rg  r  r  old_cwdold_exec_askold_session_keyr  r  r  r  r  r  r  r  r  _rtr  _cp_key_cp_baser  r  r  r  r  r  workspace_ctxworkspace_system_msg_previous_messages_previous_context_messagesr   _result_messages_next_context_messagesr  s'                                          r   r{  r{  g  s
   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%%%%%% M	 M	       
 ,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)-.G.G.J.J)K)K&++*S03%?%?@Z%[%[%( ,  FOM	 M	 M	 M	 M	 M	 M	 M	 M	 M	 M	 M	 M	 M	 M	^  	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!<!<&"
 "
 4??&''(:<LMM	
 

 7j   QW55AG	!              $???122 	999999<^0qo2 /gg!!*oo     ? ? ?=>>>>>?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 (R9 5<O=2AKO=
K7K2-O=2K77C:O=1R9 =PR9 PR9 
BR--R14R19U+<BUU+U##U+&U#'U+BXXX A-Z $Z54Z5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)Nr  scheduler   )
create_job
update_jobr-  r.  Fr   deliverlocalr8   rg  )r  r  r   r  r8   rg  r?  TrJ  r+  r   r  r  )r  rJ   r  r   r  r  r  r<  r0   r  r0  r=   )	r  r   r   r  r  r-  r.  r+  post_create_updatess	            r   r  r    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                    	 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 )	Nr
  r   )r  r-  Job not foundr  Tr  )
r  rJ   r  r   r  r  rB  r<  r  r0  )r  r   r   r  updatesr>  r  r+  s           r   r  r  +  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 )Nr
  r   )
remove_jobr  r  T)rJ  r
  )r  rJ   r  r   r  r  r  )r  r   r   r  rJ  s        r   r  r  C  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 )Nr
  r*   r  r   )get_jobr  r  Falready_runningr   )rJ  r
  rx  r8  r6   T)rc  rd  r^  rt  )rJ  r
  rx  )r0   r  r  r  r  r  rC  r  r<   r7   rB  r_  r`  r  rl  )
r  r   r
  r  r+  r  r8  r7   _profile_home_execution_profile_homes
             r   r  r  P  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 )Nr
  r*   r  r   )	pause_jobreasonr	  Tr  r  r  )r0   r  r  r 	  r  )r  r   r
  r 	  r   s        r   r  r  s  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 )
Nr
  r*   r  r   )
resume_jobTr  r  r  )r0   r  r  r	  r  )r  r   r
  r	  r   s        r   r  r    s    XXh##F /7-...$$$$$$ZF 7f55666w---r   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)
Nr   r   r  r  rb  	recursivez(Set recursive=true to delete directoriesTrJ  r   )r  rJ   r  r   rp   rq   r  r   r  r]   r   r0   shutilrmtreerq  r  r   r  r  r   r   r   rc  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)Nr   r   r  r  rb  z Cannot save: path is a directoryr   r*   r   r   T)rJ  r   r$  )r  rJ   r  r   rp   rq   r  r   r  r]   r   
write_textr0   r  r   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==?? 	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)Nr   r   r  r  zFile already existsTr   r   r*   r   r   r	  )r  rJ   r  r   rp   rq   r  r   r  r]   r   r   r	  r0   r  rH   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 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)Nr   r   new_namer  r  rb  r   r  zInvalid file namezA file named "z" already existsT)rJ  old_pathnew_path)r  rJ   r  r   rp   rq   r  r   r  r]   r   r   renamerH   r  r   rI   r  )r  r   r   r   r  r	  destnew_rels           r   r  r    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)	Nr   r   r  r  zPath already existsT)r   r	  )r  rJ   r  r   rp   rq   r  r   r  r]   r   r  rH   r   rI   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 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)Nr   r   r  r  zFile not found: Darwinr  z-RWindowszexplorer.exez/select,zxdg-openTr	  )r  rJ   r  r   rp   rq   r  r   r  r]   r   system
subprocessPopenr   r  r   rI   r  )r  r   r   r   rc  r	  s         r   r  r    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.
    r   r   Nr  r  Tr	  )r  rJ   r  r   rp   rq   r  r   r  r  r   rI   r  r
	  s        r   r  r  !  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                    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   r*   r   createFr  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   wrZ   s     r   r[   z(_handle_workspace_add.<locals>.<genexpr>^  s2      
,
,11V9A
,
,
,
,
,
,r   zWorkspace already in list)r   r   rJ  r<  )r  r0   r   r  r   rB   rG   r  r   rI   r   r  r  rJ   r   r  r   r   r   r  r  )	r  r   path_strr   auto_createrE   r   wssrZ   s	           @r   r  r  >  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   r*   r  c                 ,    g | ]}|d          k    |S r  r   )r   r 	  r"	  s     r   r^   z,_handle_workspace_remove.<locals>.<listcomp>j  s'    
3
3
3QvY(221222r   Tr!	  r0   r   r  r  r  r  )r  r   r$	  r"	  s      @r   r  r  e  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   r*   r   zpath and name are requiredzWorkspace not foundr  Tr!	  r'	  )r  r   r"	  r   r$	  r 	  s         r   r  r  o  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).
    pathsz$paths is required and must be a listc                      i | ]}|d          |S r  r   )r   r 	  s     r   r#  z-_handle_workspace_reorder.<locals>.<dictcomp>  s    )))qy!)))r   r   Tr!	  )r0   r   rc  r  r  r   r   r   r   r  r  )	r  r   r*	  r$	  by_path	reorderedseenrZ   r 	  s	            r   r  r    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   c           	         |                     dd          }|st          | d          S |                     dd          }|dvrt          | d|           S |                     dd          }d }t          5  t          j         |          }t	          |t
                    r|rUt          |          D ]0\  }}|                     d          |k    r |j        |          } n1|r |j        d	          nd }n|r |j        d	          nd }|st          j        |d            n|rt          j        |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}	|dv r|	D ]}
t          ||
           n>|dk    r8|	D ]!}
t          ||
           t          |
           "t          t                     t          ||d           t          | d|d          S )Nr   r*   r  choicedeny)r6  ri   alwaysr1	  zInvalid choice: r_  r   r  r  )r6  ri   r2	  Fr7  T)rJ  r0	  )r0   r  r5  r4  r   rc  r2  r  rZ  rQ   r0  r1  r2  r6  r7  r  )r  r   rl   r0	  r_  rV  rh  r%  r}  r  r>  s              r   r  r    s   
((<
$
$C 674555XXh''F:::77v77888((="--K G	 6 6S!!eT"" 	. 
: )% 0 0 > >HAuyy//;>>"+%)A,, ?
 /4=ieilllG*/9)%)A,,,T (S$''' 	.l3--G hl3''.. 	68C= 	6'Xc]1-=s8C=?Q?QRRRR'T155596 6 6 6 6 6 6 6 6 6 6 6 6 6 6<  	:{{>**Nw{{="/M/M.N((( ( (Q''''(x % %Q'''!!$$$$$%8999 S&e<<<<WTV44555s   5EGG	G	c                    |                     dd          }|st          | d          S |                     d          }||                     d          }||                     d          }t          |pd                                          }|st          | d          S t	          ||d	           t          | d
|d          S )Nr   r*   r  r)  r  r0	  zresponse is requiredFr7  T)rJ  r)  )r0   r  r   r   rf  r  )r  r   rl   r)  s       r   r  r    s    
((<
$
$C 674555xx
##H88H%%88H%%8>r""((**H 472333Cu5555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 rX   )ioBytesIOr  rx  sent_headersselfs    r   __init__z(_ManualCompressionMemoryHandler.__init__  s$    Z\\
r   c                     || _         d S rX   r  )r;	  rx  s     r   rA  z-_ManualCompressionMemoryHandler.send_response  s    r   c                     || j         |<   d S rX   )r9	  )r;	  r   r   s      r   rB  z+_ManualCompressionMemoryHandler.send_header  s    !&#r   c                     d S rX   r   r:	  s    r   rC  z+_ManualCompressionMemoryHandler.end_headers  s    r   c                     | j                                                             d          }|rt          j        |          ni S )Nr   )r  getvaluerN  r   r   )r;	  r3   s     r   rj   z'_ManualCompressionMemoryHandler.payload  s:    j!!##**733"%-tz#2-r   N)rO  
__module____qualname__r<	  rA  rB  rC  rj   r   r   r   r5	  r5	    s_          
  ' ' '  . . . . .r   r5	  c                    | t          j                     n| } t          t                                                    D ]\  }}|                    d          dk    rt          |                    d          p|                    d          p|           }| |z
  t          k    rt                              |d            d S )Nrx  rt  r  r  )r  rc  r   rB  r0   r[  #_MANUAL_COMPRESSION_JOB_TTL_SECONDSr  )r  rl   r+  r  s       r   "_manual_compression_cleanup_lockedrF	    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 )Nrx  rt  >   r   rT  r   focus_topicr  r  )rJ  rx  r   rH	  r  r  r  r   TrJ  r   FCompression failederror_statusr  rT  zCompression cancelledr  )r0   r   r  r  rJ  )r+  rx  rj   r   s       r   "_manual_compression_status_payloadrK	    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          ||           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  r   rI	  )rx  r   rJ	  r  r  )rx  r   r  z3Manual compression worker failed for session %s: %sCompression failed: )r5	  rs  rJ  rx  rj   _MANUAL_COMPRESSION_JOBS_LOCKr   r0   r  r   r  r  r   r=   rr   rA  r  )rl   r   memory_handlerrx  rj   r+  r  rS  s           r   _run_manual_compression_jobrP	    s   466N& 666^*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	   
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	sn   AD1 D$/D1 <BD$D1 $D((D1 +D(,D1 1
G;#GAG6GG	G	G	
GG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 )Nr   r*   r  r  r  r  @Session is still streaming; wait for the current turn to finish.r  rH	  topicr  rx  rt  )r   rH	  rx  r  r  zmanual-compress-r  T)rc  rd  r   r^  )r  rJ   r  r   r0   r   rp   rq   rh   r  rN	  rF	  r   rK	  r  r  r_  r`  rP	  rl  )r  r   r   rl   r   rH	  job_bodyr  rv  existing_payloadr+  workers               r   rr  rr  J  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 )Nr*   r  Tidle)rJ  rx  r   )	r   r   r  rN	  rF	  r   r0   r  rK	  )r  rl   r+  rj   s       r   r  r    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  r*   toolr   r   c              3      K   | ]k}t          |t                    rT|                    d           dk    0t          |                    d          p|                    d          pd          V  ldS )rN  r   r   r*   Nr   r  r0   r   rY   s     r   r[   zH_handle_session_compress.<locals>._anchor_message_key.<locals>.<genexpr>  s        a&& ,-55==F+B+B AEE&MM;QUU9%5%5;<<+B+B+B+B r   r     _tsr  ru  r   )r  r  r   ru  )	r   r  r   r0   rc  rp  r   r   rQ   )r(  r  r   r   r  r  ru  attach_counts           r   _anchor_message_keyz5_handle_session_compress.<locals>._anchor_message_key  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  r*   rh  r   \s+r  zcontext compactionzcontext compression)	ri  r   r  r   r0   r   r   r  sub)r  r   r(  r  r   r  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 )Nrc	  r  i@  i:  r  )r   r   r   r  rd	  rQ   )raw_textr6  s     r   _compact_summary_textz7_handle_session_compress.<locals>._compact_summary_text  sr    (C(( 	4nn 	4fVS#&&s88c>>#Y###C
r   r   r*   r  rH	  rS	  r  r  r  r  rR	  r  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   r*   r   c              3      K   | ]R}t          |t                    t          |                    d           p|                    d          pd          V  SdS r   r   r*   Nr   r  r   r0   rY   s     r   r[   z]_handle_session_compress.<locals>._fallback_estimate_messages_tokens_rough.<locals>.<genexpr>  sn       - -%a..-AEE&MMCQUU9-=-=CDD- - - - - -r   r   )	r   r  r0   rc  rp  r   rQ   r   r]  )r  rS  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   rr	  rs	  r*   zCompression completed.reference_message)rQ   r0   )original_messagescompressed_messagesbefore_tokensafter_tokensrH	  rq	  summaryro	  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=   )r  r|	  ro	  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=   )ru	  rv	  rw	  rx	  rH	  r	  rz	  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  r  r  r  r  rC  z3resolve_runtime_provider failed for compression: %sr  z*No provider configured -- cannot compress.r  r  r  rH  Tr  )current_tokensrH	  )rH	  z>Session stream state changed during compression; please retry.z6Session was modified during compression; please retry.F)auto_compressionr   r  rt	  rr	  rq	  compression_anchor_visible_idxcompression_anchor_message_key)r  r  r  r  r  r  r	  r	  )rJ  ri   ry	  rH	  z%Manual session compression failed: %srM	  rX   )7r  rJ   r  r   r0   r   rp   rq   rh   r|  r  r  rQ   r  r  r  r  r  runtime_providerr  r  r  rg  r  r=   rr   rA  r   r   r  rc  r  r  r  r  context_compressorcompressr  r  r  r  r  r  r  r   r]  r	  r	  r  compression_anchor_summaryr  r  r  r  r  )&r  r   ra	  re	  rh	  r   rl   rH	  r   r  r  r}	  r	  r  r  _runtime_provider
_run_agentresolved_modelresolved_providerresolved_base_urlresolved_api_keyr  r  r  r  ru	  original_stream_stateapprox_tokensr  
compressed
new_tokensry	  current_stream_statevisible_aftersummary_textsession_payloadro	  rz	  s&                                       @@r   rs  rs    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 }
    r   Nr*   r  r=  'since must be a unix timestamp (number)r   )count_conversation_roundsCONVERSATION_ROUND_THRESHOLDr=  T)rJ  rounds	thresholdshould_show)r  rJ   r  r   r0   r   r[  r\  r  r	  r	  r  )r  r   r   rl   r=  r	  r	  r	  s           r   rt  rt     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ry	  channelr	  r  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[	  r*   handoff_summaryTN)_handoff_summary_cardr   ry	  r	  r	  r  generated_atFrN  )r  r  r   r  r_	  r   )r  r   r  r   r   r  )rl   ry	  r	  r	  r  r  s         r   #_build_handoff_summary_tool_messager	     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   r	  r   r*   r	  r   ry	  r	  r	  r  T)r   ry	  r	  r	  r  r	  )r   r  r0   r   r   r=   r   r  )r   r   rj   s      r    _extract_handoff_summary_payloadr	     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rv  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.Fr   ry	  r	  r	  r  r	  )r	  r0   )rv  rc  rU	  target_payloads       r   $_is_matching_handoff_summary_messager	  !  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   r	  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.NFr*   r   r	  Try	  r	  r	  r  )r   r   r=   r   r  r0   r   r  )r   r	  rj   s      r   $_is_matching_handoff_summary_contentr	  *!  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  Fr  Tz@Failed to persist handoff summary marker in local session %s: %sN)
r  rp   rq   r  r	  r   r  r=   rr   rA  )rl   r   rp   r   r   s        r    _persist_handoff_summary_locallyr	  @!  s    ******K   uu: 	>qz"~wWW 	4	
'"""	t   Y[^`abbbuuuuus)    
"""A: 
.A: :
B+B&&B+c           
      (   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%          |          }		  |j        t          |                    5 }
	 |	Q|
                    d| f          }|                                }|$t-          |d         |	          r	 ddd           dS n+# t          $ r t.                              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'}t.                              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   NFr6   r:   r;   zstate.dbr  r   r*   r	  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  rD  r<   r7   r   rB   rG   r=   r@   r   rA   r]   r0   r  r   r   r  r	  r  r  r  r	  rr   rs   commitrA  )rl   r   r?   r  r7   r   r  r  r   marker_payloadr  r  r  r   s                 r   $_persist_handoff_summary_to_state_dbr	  T!  sC    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\\** 	d]!-,,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*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.)r	  r  r	  r	  )rl   ry	  r	  r	  r  markerr  persisted_locals           r   _persist_handoff_summaryr	  !  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.
    r   Nr*   r  r=  r	  r   )r  r	  r	  r	  z5Not enough conversation rounds to generate a summary.r  r  r  r  irL  z!Not enough messages to summarize.c                     t          | t                    r1d                    d | D                                                       S t	          | pd                                          S )Nr  c              3      K   | ]R}t          |t                    t          |                    d           p|                    d          pd          V  SdS rl	  rm	  rY   s     r   r[   zI_handle_handoff_summary.<locals>._extract_handoff_text.<locals>.<genexpr>!  sn        a&&AEE&MM;QUU9%5%5;<<     r   r*   )r   rc  rp  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   rI  s     r   r[   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(  r	  r	  s     r   r[   z*_handle_handoff_summary.<locals>.<genexpr>!  sZ           	//i0@0@AABB           r   r  r   r  rK  rh  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 )Nr  r*   r   r  )rp  r   r   r   rQ   r%  )rg	  max_lenr   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  r*   r   R   r	  rK  uc   近期可读文本不足，无法生成更完整的交接摘要，请补充一条消息后重试。zdNot enough readable text to create a useful handoff summary; please send one more message and retry.u   - 你刚讨论了：r  u   。u   - 助手已回复：rL  u2   - 当前对话存在尚未确认的后续动作。u;   - 当前信息偏少，建议补充关键点后再切换。r   z- You asked: rq  z- The assistant responded: z,- There is pending context to continue next.zH- The conversation is still short; add one more turn before summarizing.)r	  )r0   r   rQ   rp  )
rB  user_pointsassistant_pointsr	  r(  r  r   bulletsr	  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.r*   Tr   r  c                 ^    g | ]*}|                                 |                                 +S r   r!  )r   r   s     r   r^   zO_handle_handoff_summary.<locals>._summary_output_incomplete.<locals>.<listcomp>9"  s-    LLL$tzz||LLLLr   r  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  rQ   
IGNORECASEr  )r   r  	last_lines      r   _summary_output_incompletez;_handle_handoff_summary.<locals>._summary_output_incomplete0"  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_reasonr*   rO  stop_reason>   rO  
max_tokensr   )r   r  r0   r   r   )summary_resultr	  r	  r	  s      r   _agent_summary_incompletez:_handle_handoff_summary.<locals>._agent_summary_incompleteC"  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   )rp   r  r   r  r   r  r  )	r  rp   r  r  r   r  r  r0   r=   )channel_labelr  r  session_metarE   rl   s        r   _resolve_handoff_channel_labelz?_handle_handoff_summary.<locals>._resolve_handoff_channel_labelN"  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	  rt  rK  r*   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)rg  r  r	  r	  r	  is_oauthpreserve_dotsrC  )strip_tool_prefixg?temperaturerZ  rX  max_completion_tokensr	  r	  r	  r  r   r   r	  r	  r   )rh   r	  _build_api_kwargsr  _run_codex_stream_normalize_codex_responser   r   r   agent.anthropic_adapterr	  r	  rg  _anthropic_preserve_dots_anthropic_messages_create_ensure_primary_openai_clientchatrB  r	  )r  r  	user_textr	  api_messagesr   disabled_reasoningprevious_reasoningcodex_kwargsr  assistant_messager   r	  r	  
ant_kwargs
api_kwargsr0	  r  r	  r	  s                     r   _agent_text_completionz7_handle_handoff_summary.<locals>._agent_text_completionh"  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  rg  r  r  r  rC  z7resolve_runtime_provider failed for handoff summary: %sr  T)r  )rJ  ry	  r  r	  r  rH  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: )rJ  ry	  r  r	  r  rA  )r	  ),r  rJ   r  r   r0   r   r[  r\  r  r  r	  r	  r  r   rJ  rC  rr  r  r   r=   rQ   r   rp  r  r  r  r  r  r	  r  rp   rh   r  r  rr   rA  r   r  r	  r  r  r  release_clientsr  )2r  r   r   r=  r  r	  r	  r	  all_msgs_dtfilteredr(  ts_rawts_valr  r  r  r   
transcriptr	  r	  r	  r  r  r	  r	  r	  r	  r	  rp   s_objr	  r  r  r  r  r	  r  summary_system_promptsummary_user_text
first_passsecond_passr  r	  r	  r	  r	  r	  rl   r	  s2                                               @@@@@@r   ru  ru  !  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   r  rp  r   r  r`  ru   r*   zInvalid categoryzInvalid skill pathTr   r   r   r   )rJ  r   r   )r  rJ   r  r   r   r   rr  r0   rC   rG   rH   r   r	  r  )r  r   r   
skill_nameru   rR   r   
skill_files           r   r  r  Q#  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   r  rp  r   r  r`  c                 4    g | ]}|j         j        k    |S r   )r   r   )r   rZ   r
  s     r   r^   z(_handle_skill_delete.<locals>.<listcomp>x#  s'    VVVQ!(-::U:Uq:U:U:Ur   r   ra  r  T)rJ  r   )r  rJ   r  r   r	  r   r   rr  rC   r   r   r		  r  )r  r   r   r	  rR   matchesr   r
  s          @r   r  r  m#  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                    	 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t          | d          S |
                    |d         d           t          | d|t          |          d          S )Nr  r   r   r6   rG  r;   Tr   rJ  rH  rK  rI  z"section must be "memory" or "user"r   r   )rJ  r  r   )r  rJ   r  r   r<   r7   rD  r   rA   r   r	  r  )r  r   r   r7   rP  r  rc  s          r   r  r  #  s[   $i++++ $ $ $7CFF########$7777777((**Z7 7 7 7)++	)J67MM$M...9oG(;&	F		9$7@AAA
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  r  )r   rZ  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  rh  r  Tr[	  r  r   r   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  r  r   r   )r   r  r
  r  )r   rZ  r   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 rX   r
  r  s     r   r[   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 rX   r
  r  s     r   r[   z3_is_cli_tool_metadata_enrichment.<locals>.<genexpr>#  s+      IIQ-a00IIIIIIr   T)r   rc  rQ   r   r2  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   rc  rQ   r2  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                 L   	 t          |d           n4# t          $ r'}t          | t          |                    cY d}~S d}~ww xY wt          |d                   }t	          j        |          }|rt          |          }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/          | |                                |j
        dt3          |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	          }t3          |                    d                    } n|pt5          |d          }d}t7          ||          rt9                      }|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%} t/          | | dd          S t=          ||||||||&          }!|r||!_        d|!_         ||!_        |p||!_        ||!_        ||!_        ||!_!        ||!_"        ||!_#        ||!_$        ||!_%        ||!_&        ||!_'        |!                    d           t/          | |!                                |dd'z  dd          S )(z1Import a single CLI session into the WebUI store.r   NFTr  r   r  r  r  )r  r  r   r  r  r  r  r  )r  r  r  )ri   importedzSession not found in CLI storer  r2  r-  rg  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  rJ   r  r   r  r  r  rc  r  rQ   r  r#
  r 
  r  r0   r   r  r  r  rB  rh   setattrr  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r   r   _cli_origin)"r  r   r   rl   rv  
fresh_msgsr  r  r  r  attrr   r  r-  r  r  	cli_titlecli_source_tagrg  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 	2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"""yy{{ "& 
 	
 	

 
 
r  c           
      \   |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|                                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  Nrg  r  )r  r  rg  r  r  r  Fr  Tr1  )r   r  r  r0   rc  r   r  r  r\  rJ   r  r  r  r  r  r   ri  rQ   r  rj  r  r  r  r  )r  r   r  r  r  r   rg  r   s           r   r  r  $  s<    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WTaiikkZ<T.TUUVVVs2   9AB< <C4C/)C4/C4A8G  G$'G$)r  _save_yaml_config_file_get_config_pathr@  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tokenr   secretrb  
credentialc              3   D   K   | ]}|                                 v V  d S rX   )r   )r   r   r>  s     r   r[   z _mask_secrets.<locals>.<genexpr>$  s/      %H%Ha17799n%H%H%H%H%H%Hr      ••••••)r   r  rB  r   r   _mask_secrets)obj	sensitivemaskedr  r>  s       @r   rB
  rB
  $  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   >   r+   r.   r-   r,   >   r@  r  r  r  F)r   r  rJ  r[  r   r   r   )r   rZ  s     r   _parse_mcp_enabledrG
  $  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   r}  s     r   r#  z/_mcp_runtime_status_by_name.<locals>.<dictcomp>$  sd       eT"" (-yy'8'8EIIf  r   )tools.mcp_toolrI
  r=   r   rc  )rI
  statusess     r   _mcp_runtime_status_by_namerM
  $  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   rI  r  r$   Finvalid_configN)	transportrX  connect_timeoutr  rS  rx  
tool_countr  T	connectedurlhttprP
  r#  r;  stdior*   rd  envrX  rQ
  rS  rx  r   r  r	  rR
  )r   r  r  rG
  r0   r  rB
  )r   r  runtime_statusoutr  rS
  s         r   _server_summaryrZ
  $  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.Nr*   zAuthorization:\s*Bearer\s+\S+z[REDACTED CREDENTIAL])flagsr   r   r  )
r   r   r  r   r  rd	  IrQ   r]  r%  )r   r"  s     r   _mcp_safe_display_textr^
  %  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.r2  rN  r   c              3   8   K   | ]}|t          |          V  d S rX   r  r  s     r   r[   z#_mcp_schema_type.<locals>.<genexpr>.%  s-      00!a0s1vv000000r   )anyOfoneOfallOfenum)r   r  r0   rc  rp  r   )schematyp	composites      r   _mcp_schema_typerh
  (%  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   r*      r  )r   rN  rk
  r   )r   r  r0   rc  r   rB  rQ   r   r^
  r   rh
  )	re
  r"  rj
  rk
  required_namesrY
  r   propr  s	            r   _mcp_schema_summaryro
  9%  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_schemare
  re
  rq
  r  )r[	  r   r   s      r   _mcp_tool_schema_from_payloadrt
  \%  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   r*   r   ih  r  rS  r  rx  r2  )r   r^  r   rS  r  rx  schema_summary)r   r  r   r0   r^
  r  ro
  rt
  )r   r[	  server_summaryr   r   s        r   _mcp_tool_summaryrx
  h%  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  rB  r0   rc  r   r2  rx
  r   )runtime_by_nameserver_summariesr	  server_nameruntime	raw_toolsrw
  r  r[	  fallback_namery	  s              r   _mcp_tools_from_runtime_statusr
  %  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  rS  rx  )tools.registryr
  r=   get_all_tool_namesget_toolset_for_toolr   r   r   rQ   
get_schemar0   r   rx
  )	r|
  r
  r	  r9  r   toolsetr}
  re
  rw
  s	            r   _mcp_tools_from_registryr
  %  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   rZ
  r0   r   r   scfgr~
  s      r   r#  z*_handle_mcp_tools_list.<locals>.<dictcomp>%  sY       D$ 	D		?3t99dGKKD		4J4JKK  r   mcp_runtime_statustool_registrynonec                 Z    |                      dd          |                      dd          fS )Nr^  r*   r   r   )r  s    r   r  z(_handle_mcp_tools_list.<locals>.<lambda>%  s'    " 5 5swwvr7J7JK r   r  c                 r    g | ]4}|                     d           |                     d          ,|d         5S )r  rS  r   r   )r   ry	  s     r   r^   z*_handle_mcp_tools_list.<locals>.<listcomp>%  sR       #;;y!!*1++h*?*?  r   already_known_runtime_only)r	  rS  r  inventory_scopeunavailable_servers)r  r0   r   r  rM
  rB  r
  r
  r  r   r  rQ   )r  r  serversr|
  r	  r  r
  r~
  s          @r   r  r  %  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                     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   )rZ
  r0   r   r
  s      r   r^   z,_handle_mcp_servers_list.<locals>.<listcomp>%  sK       D$ 	dGKKD		$:$:;;  r   FT)r
  toggle_supportedreload_required)r  r0   r   r  rM
  rB  r  )r  r  r
  r   r~
  s       @r   r  r  %  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
  zMCP server 'z' not foundr  T)rJ  deleted)r}  r
  r  r  r0   r   r  r9
  r:
  r@  r  )r  r   r
  r  r
  s        r   _handle_mcp_server_deleter
  %  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   rA
  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  rB  r   _MASKED_PLACEHOLDER_strip_masked_values)r  rv  rT  r>  r  s        r   r
  r
  %  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
  rT
  r#  r;  rd  rW
  zurl or command is requiredrX  NT)rJ  r^  )r}  r
  r  r  r0   r   r  r   r
  rc  rJ  rJ   r\  r9
  r:
  r@  r  rZ
  )r  r   r   r
  
server_cfgr  r
  existing_cfgs           r   _handle_mcp_server_updater
  
&  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rX   r   )r'   N)r=  )rd  )r   )Fr  (  __doc__r  r  r  r7	  r   loggingr?   rh  r  r   r	  r  r	  r  r_  r  r`  pathlibr   
contextlibr   r}  r   api.agent_sessionsr   r   r	   r
   api.compression_anchorr   	getLoggerrO  rr   r'  r(  r)  TimeoutErrorrI   r  r   r  r   r[  __annotations__Lockr  r   rN	  rE	  _CRON_OUTPUT_CONTENT_LIMITr$  r   r   objectr   r  rR  r#   rc  r9  r8  r:  rK  r<   r&   r  r4   rC   rK   rT   rb   rk   rt   r   tupler   r   r   r  r   r   r   r   r	  r  r  r  rJ  r!  r*  r0  r4  r   r:  r<  rB  rT  r^  rz  r  rX  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  r  r  r  r  r  api.agent_healthr  api.request_diagnosticsr  api.system_healthr  r  r  r  r$  r  r  r  r/  r4  r<  rD  rP  rT  r[  rb  rf  rm  rs  ru  ry  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   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  
api.uploadr  r  r   r|  r!  r"  r#  r  api.providersr$  r%  r&  r'  api.onboardingr(  r)  r*  r+  r  r,  r-  r.  rv  r/  _submit_pending_rawr0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  rD  rI  rj  rM  rQ  rZ  r\  r  r  re  r  rf  rg  r  rh  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  	frozensetr  r  r  r  r  r  r  r\  rc  rn  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  r4  r  rS  r[  ri  r  r  r  r  r  r  r  r  r  r  r  r  r/  r  r  r  r  ro  rw  rx  rz  r}  r  ry  rz  r  r  r{  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r5	  rF	  rK	  rP	  rr  r  rs  rt  r	  r	  r	  r	  r	  r	  r	  ru  r  r  r  r
  r
  r
  r 
  r#
  r  r  r  r9
  r:
  r@  rB
  rG
  rM
  rZ
  r^
  rh
  ro
  rt
  rx
  r
  r
  r  r  r
  r
  r
  r
  r   r   r   <module>r
     s2&    
      				   				  				        



       				             ! ! ! ! ! !            ? > > > > >		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.. (* %  & ( ) ( ( ( ( (-D - - - -hD h h h h, $ 4    
 
4: 
#PT* 
 
 
 
+$ +4: + + + +4    $3 4    R Rd RcDj RD R R R Rj+S +d +uTD[$QU+=U7V + + + +\3 D T    c d    P #$ 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0  0  0  0 f 	   !,, *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
# # # ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #H                        8 7 7 7 7 7 6 6 6 6 6 6 9 9 9 9 9 9
c 
d 
 
 
 
d$ d d d dND    4     c3:o(>    * #* CRVJ [_    "S    0#D # # # #L#     >B   edl d     c D    4 4 4$%4 % % % %#*     .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     $(! !:!d
! Dj! 3:sTz!"	! ! ! !0: : : : : :	S 	T 	 	 	 		;D 	; 	; 	; 	;# #3 #3 # # # #L	,4 	,C 	, 	, 	, 	,T d    S    && #C&  H& 
	& & & &R+T + + + +"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 T
  tDz        F                                 "                              O N N N N N N N N N            c b b b b b b b b b b b                                                        ..**O,,33&&K00..//33HINE#%%   ;= 4T%+%6 67 < < <     @# @%+ @$ @ @ @ @C td{ 3 SW    4
=S 
=t 
=C 
=D 
= 
= 
= 
=> >t > > > > >@(                ( ( (11.. ''OOO	( 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 }g gTd
 s    @$ R   
 )((   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    BJ JdTk JU4:=N J J J JZ  B  "c":;;       36 
 
 
# 
 
 
 
- - - - - -`
 
 
 
 
"  	9 	 	 	 	 	z4 z z z z@ sD s s s sl)T    d    & 
"  fee   0  ,*P *P *PZ5 5 5B  D	 	 	5 5 585 5 5"5 5 5$) ) )     F  85 5 5pC 3 3    .c c eCHoPT>T    : tx 7 7 7t 73 7S 7Y\ 7filpfp 7 7 7 7tkc kc kc\!V !V !VH5 5 5$= = =&9* 9* 9*xD D D() ) )E( E( E(PD D D(V< V< V<r,Z ,Z ,Z^9 9 9>% %s %3 % % % % %(> > >*
0 
0 
0$? $? $?N  F8 8 8 8.5} 5} 5}pXa Xa Xav C  Z_bfZf  ko        D  $" " " 
"
 " " " " " " "R  "	f f f 
f
 f f f f f f fRu u upG G G GVS    $  <c c cL9 9 9<C C C0
> 
> 
> K  K  KF	. 	. 	.	. 	. 	.0 0 000 0 0.0 0 0,0 0 040 0 0*0 0 0D0 0 0:$7 $7 $7N7 7 77 7 7 = = =886 86 86v: : : . . . . . . . .(4 4 4 4  6( ( (V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: : :&M M M.6 f     F t    & V     d W[    , t X\    $l l l^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	 	 	  .  ,  <  <  $5 5 5& +   ""Q "Q "Q "Q "Qs%   5X AYY9[ [+*[+