
    }-jW                       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mZ ddlmZ  ej        e          ZddlmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 dd	l4m5Z5  e	j6                    Z7d
 Z8	 ddl9m:a: n# e;$ r da:Y nw xY wd Z<de=de>fdZ?dde@de@fdZAdddde=de>deBfdZCdde=de=de=deBfdZDde=fdZEddlFmGZGmHZH ddlImJZJ h d ZKd!ZLh d"ZMd#ZNh d$ZOd% ZPd& ZQdd'ZRdd(ZSd)eBdz  d*e=d+e=d,e=deBf
d-ZTde=fd.ZU eVd/h           eVd0h           eVd1h           eVd1h           eVd2h           eVd3h           eVd4h          d5ZWeBeXdz  eVe=         f         eYd6<   d7ed8e=de>fd9ZZd:eBde=fd;Z[dd<d=e=d>e=d*e=d:eBfd?Z\d@e=de=fdAZ]d@e=de=fdBZ^d@e=de=fdCZ_d@e=de>fdDZ`de=fdEZa ejb        dF          Zc ejb        dG          Zdd7e=de=fdHZed7e=de=fdIZfddJd@e=dKe>de=fdLZgdM ZhdN ZidO Zjde@fdPZkdQe=de>fdRZldSe=dTe=deme=ene=         f         fdUZoddVe=dWe=dXe=de>fdYZpde>fdZZqdderderfd\ZsddVe=dWe=dXe=de@fd]ZtddVe=dWe=dXe=de@fd^Zud_e=de>fd`Zvd_e=de>fdaZwdbe=fdcZxde=fddZyddedfe>deme=e=f         fdgZz	 	 	 ddSe=dTe=dVe=dWe=dXe=demee=         e=f         fdhZ{dSe=dTe=demee=         e=f         fdiZ|dSe=dTe=demee=         e=e=f         fdjZ}dddkdSe=dTe=dle>demee=         e=e=f         fdmZ~dd+e=d_e=dne=doe=dpe=ddfdqZdSe=dTe=dee=         fdrZdoe=de>fdsZdd+e=dSe=dTe=dte=fduZdd+e=dSe=dTe=dQe=fdvZdw Zdx Zdy Zdz Zd{ Zd| Zd} Zd~ Zdde=dz  de@de=dz  fdZd Zd Zd Zd Zd Zd ZdZefde@de=fdZdde@deBfdZde@de@fdZddZd Zde>fdZd Zd Z	 ddddddZdeBde>fdZde=de>fdZdS )zt
Hermes Web UI -- SSE streaming engine and agent thread runner.
Includes Sprint 10 cancel support via CANCEL_FLAGS.
    N)Path)Optional)
get_configSTREAMSSTREAMS_LOCKCANCEL_FLAGSAGENT_INSTANCESSTREAM_PARTIAL_TEXTSTREAM_REASONING_TEXTSTREAM_LIVE_TOOL_CALLSSTREAM_GOAL_RELATEDPENDING_GOAL_CONTINUATIONLOCKSESSIONSSESSION_DIR_get_session_agent_lock_set_thread_env_clear_thread_envregister_active_runupdate_active_rununregister_active_runSESSION_AGENT_LOCKSSESSION_AGENT_LOCKS_LOCKresolve_model_provider"resolve_custom_provider_connectionmodel_with_provider_context)redact_session_data_redact_text)visible_messages_for_anchor)meter)$append_turn_journal_event_for_streamc                  P    dD ]"} 	 t          |            # t          $ r Y w xY wdS )a  Import tools.skills_tool and tools.skill_manager_tool outside any lock.

    First-time module imports can trigger heavy initialisation (disk I/O,
    transitive imports, plugin discovery).  Performing those imports while
    holding ``_ENV_LOCK`` serialises every concurrent session behind the
    slowest import.  Prewarming ensures the modules are already in
    ``sys.modules`` before the lock is acquired, so the lock body only
    does lightweight attribute patching.

    We cannot place these at module top-level because ``tools.*`` lives
    in the hermes-agent package which may not be on ``sys.path`` at
    import time (Docker volume-mount ordering).  A dedicated helper
    keeps the lazy-import try/except in one place and makes the intent
    explicit.
    )ztools.skills_toolztools.skill_manager_toolN)
__import__ImportError)	_mod_names    #/root/hermes-webui/api/streaming.py_prewarm_skill_tool_modulesr'   /   sT      G  		y!!!! 	 	 	D	 s   
##AIAgentc                  R    t           	 ddlm }  | a n# t          $ r Y nw xY wt           S )a^  Return AIAgent class, retrying the import if the initial attempt failed.

    auto_install_agent_deps() in server.py may install missing packages after
    this module is first imported (common in Docker with a volume-mounted agent).
    Re-attempting the import here picks up the newly installed packages without
    requiring a server restart.
    Nr   r(   )r)   	run_agentr$   )_clss    r&   _get_ai_agentr-   L   sL     	111111GG 	 	 	D	Ns    
err_textreturnc                     t          | pd                                          }d|v p?d|v p;d|v p7d|v p3d|v p/d|v p+d|v p'd	|v p#d
|v pd|v pd|v pd|v pd|v pd|v pd|v od|v od|v S )zAReturn True when provider text looks like quota/usage exhaustion. zinsufficient creditzcredit balancezcredits exhaustedzmore creditszcan only affordzfewer max_tokensquota_exceededzquota exceededzexceeded your current quotazplan limit reachedusage_limit_exceededzusage limit exceededzreached the limit of messageszused up your usageplanlimitreached)strlower)r.   
_err_lowers     r&   _is_quota_error_textr:   ^   s   X^$$**,,J+ 	Xz)	X*,	X Z'	X 
*		X
 +	X z)	X z)	X )J6	X  :-	X "Z/	X "Z/	X +j8	X  :-	X j VW
%:VyJ?V!    x   defaultc                     	 t                      }|                    di                               d|           }t          |          }|dk    r| S |S # t          $ r | cY S w xY w)z;Resolve clarify timeout from config, with bounded fallback.clarifytimeoutr   )r   getint	Exception)r=   cfgrawtimeout_secondss       r&   _clarify_timeout_secondsrG   u   sx    llggi$$((G<<c((aN   s   AA A A"!A"Fsilent_failureerr_strrI   c                   t          | pd          } |                                 }|t          |          j        nd}t	          |           }| od| v p|duod|v pd|v pd|v pd|v pd|v pd	|v }d
| v pd|v pd|v pd|v pd|v pd|v pd|v pd|v }| od|v pd| v p|duod|v }|rddddS |rddddS |rddddS |rddd dS |rd!d"d#dS d$d%ddS )&zClassify provider/agent failure text for WebUI apperror UX.

    Keep this string-based until hermes-agent exposes stable structured
    provider error classes for Codex OAuth plan limits.
    r1   N401AuthenticationErrorauthenticationunauthorizedzinvalid api keyinvalid_api_keyzno cookie auth credentials404z	not foundzdoes not existzmodel not foundmodel_not_foundzinvalid modelzdoes not match any known modelzunknown modelz
rate limit429RateLimitErrorzOut of creditsquota_exhaustedzYour provider account is out of credits or usage. Top up, wait for the plan window to reset, or switch providers via `hermes model`.)labeltypehintzRate limit reached
rate_limitzaRate limit reached. The fallback model (if configured) was also exhausted. Try again in a moment.Authentication failedauth_mismatchThe selected model may not be supported by your configured provider or your API key is invalid. Run `hermes model` in your terminal to update credentials, then restart the WebUI.zModel not foundzThe selected model was not found by the provider. Check the model ID in Settings or run `hermes model` to verify it exists for your provider.zNo response from providerno_responsezThe provider returned no content and no error. This often means a usage/rate limit was hit silently. Check provider status, switch providers via `hermes model`, or try again in a moment.Errorerror)r7   r8   rW   __name__r:   )	rJ   excrI   r9   	_exc_name	_is_quota_is_auth_is_not_found_is_rate_limits	            r&   _classify_provider_errorrg      s3    '-R  GJ&)oS		""2I$W--I 	
W :4F$9Y$F::-: +: !J.	:
 !J.: ,z9  	 	)*$	)z)	) 
*	) 
*		)
 j(	) ,z9	) j(  $m 
"mew&6m3d?;lO_clOl   
%% [
 
 	

  
) w
 
 	

  
,# I
 
 	

  
&% d
 
 	

  
0 " Q
 
 	
 gr:::r;   r1   messageerr_typerX   c                    t          | pd          }|r!t          |                                          nd}|p||d}|r||d<   |r;|}t          |          dk    r|dd                                         dz   }|r||d<   |S )	zABuild a bounded, redacted apperror payload with provider details.r1   )rh   rW   rX   i  Ni     …details)r7   r   striplenrstrip)rh   ri   rX   _message_safe_messagepayload_detailss          r&   _provider_error_payloadrt      s    7=b!!H6>FL**00222BM - 98LLG  * x==4--//%7H 	*!)GINr;   c                     ddl } ddl}dg}|                    d           |                    d|j                    | j                            d          }|r|                    d|            n|                    d           d	 |j        D             }|rw|                    d
           |dd         D ]}|                    d|            t          |          dk    r)|                    dt          |          dz
   d           n|                    d           |                    d           |                    d           |                    d           |                    d           |                    d           |                    d           |                    d           |                    d           |                    d           |                    d           d                    |          S )u  Return a multi-line diagnostic string for the "AIAgent not available" path.

    The bare ImportError ("AIAgent not available -- check that hermes-agent is
    on sys.path") leaves users guessing at which python is running, where it's
    looking, and what to fix. We assemble the same evidence a maintainer would
    ask for first (issue #1695): the python that's running, the agent_dir env
    var if set, the sys.path entries that mention 'hermes', and the most-common
    fix (`pip install -e .` in the agent dir).

    Kept as a separate helper so it stays out of the hot path until we actually
    need to raise — building it on every successful import would be wasted work.
    r   Nz?AIAgent not available -- check that hermes-agent is on sys.pathr1   z  python:  HERMES_WEBUI_AGENT_DIRz  HERMES_WEBUI_AGENT_DIR: z#  HERMES_WEBUI_AGENT_DIR: (not set)c                 j    g | ]0}d |                                 v sd|                                 v .|1S )hermesagent)r8   .0ps     r&   
<listcomp>z0_aiagent_import_error_detail.<locals>.<listcomp>   s<    VVVaAGGII(=(=AGGIIAUAUAUAUAUr;   z+  sys.path entries mentioning hermes/agent:   z    - z    ... and z morez0  sys.path: (no entries mention hermes or agent)zD  Most common fix: install the agent in editable mode so its modulesz  appear on sys.path:z    cd /path/to/hermes-agentz    pip install -e .z  Then restart the WebUI.zI  Full troubleshooting: docs/troubleshooting.md ("AIAgent not available")
)	ossysappend
executableenvironrA   pathrn   join)_os_syslines	agent_dirrelevantentrys         r&   _aiagent_import_error_detailr      s#    NOE	LL	LL0t00111 899I <=)==>>>>:;;; WV49VVVH IBCCCbqb\ 	+ 	+ELL)%))****x==1LL@H(9@@@AAAGHHH	LL	LLWXXX	LL()))	LL	LL/000	LL'(((	LL	LL,---	LL	LL\]]]99Ur;   )get_session
title_from)set_last_workspace>   namerolecontentrefusal
tool_callstool_call_idi  @>   
used_modelused_providerrequested_modelrequested_provider)llm_gatewaygatewaymetadataresponse_metadatarouting_metadatausage>   r_   modelscorereasonstatusattemptproviderselected	timestamp
latency_msattempt_indexselection_reasonc                    | d S t          | t          t          t          t          f          rSt          |                                           }|sd S t          | t          t          t          f          r| n	|d d         S d S )N   )
isinstancer7   rB   floatboolrm   )valuetexts     r&   _clean_gateway_routing_scalarr   %  sy    }t%#sE4011 N5zz!! 	4"53t*<==Muu4:M4r;   c                 2    t           t                    sd S t           fdt          D                       s(t                               d          t
                    r S t          D ],}                     |          }t          |          }|r|c S -d S )Nc              3       K   | ]}|v V  	d S N )r{   krr   s     r&   	<genexpr>z1_find_gateway_metadata_payload.<locals>.<genexpr>3  s'      
A
AA1<
A
A
A
A
A
Ar;   routing)r   dictany_GATEWAY_ROUTING_TOP_LEVEL_KEYSrA   list_GATEWAY_ROUTING_CONTAINER_KEYS_find_gateway_metadata_payload)rr   keynestedfounds   `   r&   r   r   0  s    gt$$ t

A
A
A
A!@
A
A
AAA ZPWP[P[\ePfPfhlEmEm .  S!!.v66 	LLL	4r;   c                 
   t          |           }|sdS i }t          D ]+}t          |                    |                    }||||<   ,d|vrt          |          }|||d<   d|vrt          |          }|||d<   g }	|                    d          }
t	          |
t
                    ro|
dd         D ]d}t	          |t                    si }t          D ]+}t          |                    |                    }||||<   ,|r|	                    |           e|	r|	|d<   t          |                    d          pd          
                                                                }t          |                    d          pd          
                                                                }t          |                    d          pd          
                                                                }t          |                    d          pd          
                                                                }t          |o|o||k              }t          |o|o||k              }d	 |	D             }d
 |D             }t          d |	D                       }t          |pt          |          dk    p|          }|                    d          s|                    d          s|	s|s|sdS ||d<   ||d<   ||d<   |S )a.  Return safe LLM Gateway routing metadata, or None when absent.

    LLM Gateway response metadata can contain provider/model routing details,
    but WebUI must only persist display-safe scalars and a bounded routing list.
    Secrets or provider-specific request objects are deliberately ignored.
    Nr   r   r      r   r1   r   c                     g | ]_}|                     d           t          |                     d           pd                                                                          `S )r   r1   rA   r7   rm   r8   r{   as     r&   r}   z7_normalize_gateway_routing_metadata.<locals>.<listcomp>m  sk       55AEE*#$$**,,2244  r;   c                     h | ]}||S r   r   rz   s     r&   	<setcomp>z6_normalize_gateway_routing_metadata.<locals>.<setcomp>r  s    #H#H#H!a#HA#H#H#Hr;   c              3      K   | ]N}t          |                    d           pd                                                                          dv V  OdS )r   r1   >   r_   failedr@   rejectedN)r7   rA   rm   r8   r   s     r&   r   z6_normalize_gateway_routing_metadata.<locals>.<genexpr>s  sk       " " 	AEE(OO!r""((**00226``" " " " " "r;      provider_changedmodel_changedhas_failover)r   r   r   rA   r   r   r   _GATEWAY_ROUTING_ATTEMPT_KEYSr   r7   rm   r8   r   r   rn   )rr   r   r   src
normalizedr   r   fallback_modelfallback_providerr   raw_routingr   clean_attemptr   requested_provider_normr   requested_model_normr   r   attempted_providersdistinct_attempted_providersfailed_before_selectionr   s                          r&   #_normalize_gateway_routing_metadatar   =  s    )
1
1C tJ. $ $-cggcll;;#JsO
**6GG%,:J():--9:LMM(/@J+,G'')$$K+t$$ 
."3B3' 		. 		.Ggt,, M4 / /5gkk#6F6FGG$).M#& .}--- ( '
9
77=2>>DDFFLLNNM!*..1E"F"F"L"MMSSUU[[]]Z^^L117R88>>@@FFHHJz~~.?@@FBGGMMOOUUWWMr.Er-[rJrssc(<cOcAcddM   
 $I#H/B#H#H#H ! " "" " "   (lC0L,M,MPQ,QlUlmmL 	''+5>>,+G+GKRVfjw t%5J!""/J!-J~r;   c           
         g }t          |t                    r|                    |                    d          |                    d          |                    d          |                    d          |                    d          |                    d          |g           dD ](}| $|                    t          | |d                      )|D ]}t          |||          }|r|c S d S )	Nr   r   r   r   r   r   )llm_gateway_metadatagateway_metadatalast_response_metadatar   r   
last_usager   r   )r   r   extendrA   r   getattrr   )ry   resultr   r   
candidatesattr	candidater   s           r&   !_extract_gateway_routing_metadatar     s   J&$ 	JJ}%%JJy!!JJz""JJ*++JJ)**JJw
 	 	 	 	: 	: geT488999  	8+1
 
 


  		4r;   profile_runtime_env	workspace
session_idprofile_homec                 v    t          | pi           }|                    t          |          d||d           |S )aA  Build thread-local agent env with per-run values overriding profile defaults.

    Profile runtime env may include TERMINAL_CWD from config.yaml. Passing it as
    **kwargs alongside an explicit TERMINAL_CWD raises TypeError before the
    agent starts, so merge into one dict first and let the active workspace win.
    1)TERMINAL_CWDHERMES_EXEC_ASKHERMES_SESSION_KEYHERMES_HOME)r   updater7   )r   r   r   r   envs        r&   _build_agent_thread_envr     sP     "(b
)
)CJJI(#	     Jr;   c                 2   t          | t                    r`t          |                     d          p+|                     d          p|                     d          pd                                          S t          | pd                                          S )Nr   filenamer   r1   )r   r   r7   rA   rm   )atts    r&   _attachment_namer     s{    #t \3776??Rcggj&9&9RSWWV__RPRSSYY[[[syb>>!!!r;   z	image/pngz
image/jpegz	image/gifz
image/webpz	image/bmpimage/svg+xml)s   PNG

s   s   GIF87as   GIF89as   RIFFs   BMN_IMAGE_MAGICr   mimec                    |                     d          sdS |                    dd          d         }|dk    rdS 	 |                     d          5 }|                    d	          }d
d
d
           n# 1 swxY w Y   n# t          $ r Y dS w xY wt
                                          D ]#\  }}||                     |          r||v r dS $dS )zCheck that the file's first bytes match the expected image MIME type.

    Uses simple magic-number detection (no external dependency). SVG is
    allowed through because it is text-based and has no binary signature.
    image/F;r   r   r   Trb   N)
startswithsplitopenreadOSErrorr   items)r   r   	mime_basefhheadmagicmimess          r&   _is_valid_imager    s+    ??8$$ u

3""1%IO##tYYt__ 	772;;D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   uu$**,,  u!7!7I<N<N445s5   B  A4(B  4A88B  ;A8<B   
BBrD   c                    |                      d          pi }t          |                     dd          pd                                                                          }|dvrd}|dk    rdS |dk    rdS |                      d          pi }|                     d          pi }t          |                     d	          pd
                                                                          }t          |                     d          pd
                                          }t          |                     d          pd
                                          }|dvs|s|rdS dS )a  Return ``"native"`` or ``"text"`` based on config, mirroring
    ``agent/image_routing.py:decide_image_input_mode``.

    The agent has this logic, but the WebUI's ``_build_native_multimodal_message``
    was unconditionally embedding images as native ``image_url`` parts, completely
    bypassing ``image_input_mode``.  This caused silent failures when the main model
    does not support images and the fallback model is also text-only (#21160-related).
    ry   image_input_modeauto)r  nativer   r  r   	auxiliaryvisionr   r1   r   base_url)r1   r  r   )rD   	agent_cfgmodeauxr  r   
model_namer  s           r&   _resolve_image_input_moder    s[      &BIy}}/88BFCCIIKKQQSSD---xxv~~v ''+


$"CWWX$"F6::j))/R006688>>@@HVZZ((.B//5577J6::j))/R006688H|##z#X#v
 8r;   rD   workspace_ctxmsg_textc          	      p   |s| |z   S |t          |          dk    r| |z   S d| |z   dg}t          |                                                                          }d}|pg D ]}t	          |t
                    st          |                    d          pd                                          }	|	sR	 t          |	                                                                          }
|
	                    |           |

                                s|
                                j        }|dk    s|t          k    rt          |                    d          pd                                          p t          j        |
j                  d         pd}|                    d          rt%          |
|          sYt'          j        |
                                                              d	          }n# t.          $ r Y w xY w|                    d
dd| d| id           |dz  }|r|n| |z   S )uu  Build native multimodal content parts for current-turn image uploads.

    WebUI uploads files into the active workspace. For image files, pass the
    bytes to Hermes as OpenAI-style image_url data URLs so vision-capable main
    models can consume them in the same request. Non-image files intentionally
    stay as text path attachments so the agent can inspect them with file tools.

    When *cfg* is provided, respects ``agent.image_input_mode`` — if the resolved
    mode is ``"text"``, returns a plain string (attachments are not embedded) so
    the agent's text-mode pipeline (``vision_analyze``) handles images.
    Nr   )rW   r   r   r   r1   r   r  ascii	image_urlurlzdata:z;base64,)rW   r#  r   )r  r   
expanduserresolver   r   r7   rA   rm   relative_tois_filestatst_size_NATIVE_IMAGE_MAX_BYTES	mimetypes
guess_typer   r  r  base64	b64encode
read_bytesdecoderC   r   )r  r   attachmentsr   rD   partsworkspace_rootimage_countr   raw_pathr   sizer   datas                 r&    _build_native_multimodal_messager9    sc     (x'' 4S99VCCx''mh&>??@E)__//1199;;NK b  #t$$ 	swwv,"--3355 		>>,,..6688D ^,,,<<>> 99;;&DqyyD#:::swwv,"--3355c):Nty:Y:YZ[:\:b`bD??8,, OD$4O4O #DOO$5$566==gFFDD 	 	 	H	!=!=!=t!=!=>
 
 	 	 	 	q=55]X%==s&   7AG7*G7?A<G7=9G77
HHr   c                 8   | sdS t          |           }t          j        dd|t          j        t          j        z            }t          j        dd|t          j        t          j        z            }t          j        dd|t          j        t          j        z            }t          j        dd|t          j        t          j        z            }t          j        dd|t          j                  }t          j        d	d|                                          }|S )
z:Remove common reasoning/thinking wrappers from model text.r1   z<think>.*?</think> flagsz"<\|channel\|>thought.*?<channel\|>z<\|turn\|>thinking\n.*?<turn\|>z&^\s*(the|ther)\s+user\s+is\s+asking.*$a*  ^\s*(?:here(?:'s| is) (?:a |my )?(?:thinking|thought) (?:process|trace|through)\b[^\n]*\n?|let me (?:think|work|reason|analyze|walk) (?:through|about|this|step)\b[^\n]*\n?|i(?:'ll| will) (?:think|work|reason|analyze|break this down)\b[^\n]*\n?|(?:okay|alright|sure|of course),?\s+let me\b[^\n]*\n?)\s+)r7   resub
IGNORECASEDOTALL	MULTILINErm   r   ss     r&   _strip_thinking_markuprF  5  s     rD		A
$c1BMBI4MNNNA
4c1BMTVT]D]^^^A
13QSQZAZ[[[A
8#qXZXdHdeeeA 		C 	Qbm	 	 	A 	vsA$$&&AHr;   c                    | s| S t          |           }|                                }d|vrd|vr| S d}d| d}d| d}t          j        | d| d|t          j        t          j        z  	          }t          j        | d
d|t          j        t          j        z  	          }t          j        dd|t          j        	          }|                                S )u  Strip XML-style function_calls blocks that DeepSeek and similar models
    emit in their raw response text.  These blocks are processed separately as
    tool calls; leaving them in the assistant content causes them to render
    visibly in the chat bubble.

    Handles both complete blocks (<function_calls>…</function_calls>) and
    partial/orphaned opening tags that may appear at the tail of a stream.
    Also handles variants like <｜DSML｜function_calls> from DeepSeek on Bedrock.
    function_callsdsmlu   (?:\s*｜\s*DSML\s*[｜|]\s*)?<z</zfunction_calls>z>.*?r1   r<  z
(?:>|$).*$u   <\s*｜\s*DSML\s*[｜|]\s*)r7   r8   r?  r@  rA  rB  rm   )r   rE  _lo_dsml_prefixopen_tag	close_tags         r&   _strip_xml_tool_callsrO  K  s     D		A
''))Cs""vS'8'84L0L000H3l333I
%%)%%
	mbi'		 	 	A 	   
	mbi'		 	 	A 	,b!2=IIIA7799r;   c                 \   t          | pd          }t          j        dd|t          j                  }t          j        dd|t          j                  }|                    d          }t          j        dd|                                          }t          |          rdS |dd	         S )
z?Sanitize LLM-generated title text before persisting to session.r1   zB^\s*(?:[*_`~]+\s*)?(?:session\s+title|title)\s*:\s*(?:[*_`~]+\s*)?r<  z^\s*title\s*:\s*z
 	
"'`*_~r>  r;  NP   )rF  r?  r@  rA  rm   _looks_invalid_generated_titlerD  s     r&   _sanitize_generated_titlerS  s  s    tzr**A
M
	m		 	 	A 	"B???A	 !!A
vsA$$&&A%a(( rSbS6Mr;   c                 z   t          | pd          }|                                sdS t          t          j        d|t          j                  pt          j        d|t          j                  pt          j        d|t          j                  pt          j        d|t          j                  pt          j        d|t          j                  pbt          j        d	|t          j                  pAt          j        d
|t          j                  p t          j        d|t          j                            S )Nr1   Tz/<think>|<\|channel\|>thought|<\|turn\|>thinkingr<  z^\s*(the|ther)\s+user\s+z^\s*user\s+\w+\s+z$\b(they|user)\s+want(s)?\s+me\s+to\bz(^\s*(i|we)\s+(should|need to|will|can)\bz^\s*let me\bz2^\s*here(?:'s| is) (?:a |my )?(?:thinking|thought)zA^\s*(ok|okay|done|all set|complete|completed|finished)\b[\s.!?]*$)r7   rm   r   r?  searchrA  rD  s     r&   rR  rR    s(   DJBA7799 t
	Dar}]]] 	s90!2=III	s9)1BMBBB	s 9<ar}UUU	s 9@!2=YYY		s
 9_ar}===	s 9JAUWUbccc	s 9Y[\dfdqrrr	 	 	r;   c                 :   t          | t                    rg }| D ]}t          |t                    st          |                    d          pd                                          }|dv rL|                    t          |                    d          p|                    d          pd                     t          d                    |          	                                          S t          t          | pd          	                                          S )z7Extract plain text from mixed message content payloads.rW   r1   )r1   r   
input_textoutput_textr   r   r   )
r   r   r   r7   rA   r8   r   rF  r   rm   )r   r3  r|   ptypes       r&   _message_textrZ    s    % @ 	K 	KAa&& f+,,2244EAAASv!H!%%	2B2B!HbIIJJJ%dii&6&6&<&<&>&>???!#ekr"2"2"8"8":":;;;r;   z,^\s*\[Workspace::v1:\s*(?:\\.|[^\]\\])+\]\s*z^\s*\[Workspace:[^\]]+\]\s*c                 t    t          | pd                              dd                              dd          S )Nr1   \z\\]z\])r7   replacer   s    r&   _escape_workspace_prefix_pathr`    s2    tzr??""40088eDDDr;   c                 (    dt          |            dS )Nz[Workspace::v1: z]
)r`  r_  s    r&   _workspace_context_prefixrb    s    F;DAAFFFFr;   include_legacyrd  c                    t          | pd          }t                              d|d          }|r#||k    rt                              d|d          }|                                S )zDRemove WebUI-injected workspace tags without eating user-typed text.r1   r   )count)r7   _WORKSPACE_PREFIX_REr@  _LEGACY_WORKSPACE_PREFIX_RErm   )r   rd  r   strippeds       r&   _strip_workspace_prefixrj    sh    
OOE#''E';;H G(e++.222uA2FF>>r;   c                    d}d}| pg D ]}t          |t                    s|                    d          }|dk    r0t          |                    d                    }|s|r|}\|r|r n]nU|dk    rO|rMt          |                    d                    }|                    d          r|rt	          |          r|r|}|r|r n|dd         |dd         fS )	zReturn (first_user_text, first_assistant_text) snippets for title generation.

    Prefer the first substantive assistant answer in the opening exchange,
    skipping empty placeholders and assistant tool-call preambles.
    r1   r   userr   	assistantr   N  )r   r   rA   rZ  rR  messages	user_text	asst_textmr   r   s         r&   _first_exchange_snippetsrt    s*    II^  !T"" 	uuV}}6>>%aeeI&6&677I  %	 Y [  Y %aeeI&6&677I uu\"" I 9WXa9b9b  &%	 	 	ETcT?IdsdO++r;   c                    d}d}t          | pg           D ]}t          |t                    s|                    d          }|dk    rP|sNt	          |                    d                    }|                    d          r|rt          |          r~|r|}n.|dk    r(|s&t	          |                    d                    }|r|}|r|r n|dd         |dd         fS )	zReturn (last_user_text, last_assistant_text) snippets for title refresh.

    Walks the message list backwards to find the last user+assistant pair,
    skipping empty or tool-call-only assistant messages.
    r1   r   rm  r   r   rl  Nrn  )reversedr   r   rA   rZ  rR  ro  s         r&   _latest_exchange_snippetsrw    s    IIhn"%%  !T"" 	uuV}};y%aeeI&6&677Iuu\"" I 9WXa9b9b  &%	V^^I^%aeeI&6&677I &%	 	 	ETcT?IdsdO++r;   c                 T   d}| pg D ]}t          |t                    r|                    d          dk    rp|                    dd          }t          |t                    rd                    d |D                       }t          |                                          r|dz  }|S )	z9Count the number of user messages (rough exchange count).r   r   rl  r   r1   r;  c              3      K   | ]H}t          |t                    |                    d           dk    0|                    dd          V  IdS )rW   r   r1   Nr   r   rA   rz   s     r&   r   z#_count_exchanges.<locals>.<genexpr>  s\      "y"yTUW[I\I\"yabafafgmananrxaxax155#4#4axaxaxax"y"yr;   r   )r   r   rA   r   r   r7   rm   )rp  rf  rs  r   s       r&   _count_exchangesr{    s    E^  a 	155==F#:#:eeIr**G'4(( z(("y"yg"y"y"yyy7||!!## 
Lr;   c                      	 ddl m}   |             }|                    dd          }t          |                                                                          r"t          |          dk    rt          |          ndS # t          $ r Y dS w xY w)z9Read the auto_title_refresh_every setting (0 = disabled).r   load_settingsauto_title_refresh_every0)
api.configr~  rA   r7   rm   isdigitrB   rC   )r~  settingsvals      r&   _get_title_refresh_intervalr    s    ,,,,,, =??ll5s;;s88>>++3355M#c((Q,,s3xxxAM   qqs   A<A? ?
BBcurrent_titlec           	      \   t          |d          pd}|sdS t          j        ddt          | pd                                                    }t          j        ddt          |dd         pd                                                    }|r|sdS ||k    p|                    |          S )z<Heuristic: title equals first-message substring placeholder.r1   Fr>  r;  N@   )r   r?  r@  r7   rm   r  )r  rp  derivedcurrentr   s        r&   _is_provisional_titler    s    2&&,"G ufVS#m&9r":":;;AACCGvsC(:$;$;<<BBDDI ) ui@9#7#7#@#@@r;   rq  assistant_textc                 B    d| d d          d|d d          }ddg}||fS )NzUser question:
rn  z

Assistant answer:
a  Generate a short session title from this conversation start.
Use BOTH the user's question and the assistant's visible answer.
Return only the title text, 3-8 words, as a topic label.
Do not use markdown, bullets, labels, or prefixes like Session Title:.
Do not output a full sentence.
Do not output acknowledgements or completion phrases like OK, done, or all set.
Do not describe internal reasoning.
Bad: The user is asking..., OK, all set.
Good: Title Generation Test, Clarify Dialog Layout, GitHub Issue Triagea  Rewrite this conversation start as a concise noun-phrase title.
Use the actual topic, not the task outcome.
Return title text only.
Do not use markdown, bullets, labels, or prefixes like Session Title:.
Never output acknowledgements, completion status, or meta commentary.r   )rq  r  qapromptss       r&   _title_promptsr    sJ    	ZIdsdO	Z	ZNSWTWSWDX	Z	ZBVTG( w;r;   r   r   r  c                    d                     t          | pd                                          t          |pd                                          t          |pd                                          g          }d|v pd|v S )Nr;  r1   minimaxzminimaxi.com)r   r7   r8   )r   r   r  r   s       r&   _is_minimax_router  4  s    88HN!!##EKR  HN!!##  D
 6$ 66r;   c                  .   	 ddl m}   | d          }|                    dd          pd}|                    dd          pd}|                    dd          pd}t          |p|p|o|                                dk              S # t
          $ r Y d	S w xY w)
zQReturn True when any auxiliary title_generation config field is meaningfully set.r   _get_auxiliary_task_configtitle_generationr   r1   r   r  r  F)agent.auxiliary_clientr  rA   r   r8   rC   )r  tgr   r   r  s        r&   _aux_title_configuredr  =  s    EEEEEE''(:;;66*b))/Rw##)r66*b))/RERXR(*Qx~~7G7G67QSSS   uus   BB 
BB      .@c                 T   	 ddl m}  |d          }|                    d          }|| S 	 t          |          }n5# t          t
          f$ r! t                              d||            | cY S w xY w|dk    r|S t                              d||            | S # t          $ r | cY S w xY w)a  Return the configured timeout (seconds) for auxiliary title generation.

    Only accepts positive numeric values.  Falls back to *default* when the
    value is ``None``, non-numeric, zero, or negative, and emits a debug log
    so mis-configurations are visible in server output.
    r   r  r  r@   Nz;aux title timeout: non-numeric value %r, falling back to %sz<aux title timeout: non-positive value %s, falling back to %s)	r  r  rA   r   
ValueError	TypeErrorloggerdebugrC   )r=   r  r  rE   r   s        r&   _aux_title_timeoutr  I  s    EEEEEE''(:;;ffY;N	#JJEEI& 	 	 	LLVX[]deeeNNN	 199LSUZ\cddd   s7   )B = B /A/,B .A//
B :B B'&B'c                     dS )Ni   r   r   r   r  s      r&   _title_completion_budgetr  b  s	     3r;   c                 F    t          dt          | ||          dz            S )Ni      )maxr  r  s      r&   _title_retry_completion_budgetr  k  s$    t-hxHH1LMMMr;   r   c                 
    | dv S )N>   
llm_lengthllm_length_auxr   r   s    r&   _title_retry_statusr  o  s        r;   c                 
    | dv S )u  Statuses where re-issuing the next prompt against the same model
    produces the same failing shape (model burned its budget on hidden
    reasoning, hit a hard provider gate, etc.).

    Short-circuit the prompt-iteration loop so we don't issue a second
    full-budget LLM call (and twice the GPU/credit burn) only to land in
    the same fallback path. See issue #2083.

    Add a status here only when retrying the next prompt is provably
    wasted work (single-call signal already establishes that the next
    call will return the same shape). Length-truncation WITHOUT
    reasoning is NOT in the set — that's legitimately recoverable by
    a larger budget on a different prompt and stays in
    :func:`_title_retry_status`.
    >   llm_empty_reasoningllm_empty_reasoning_auxr   r  s    r&   %_title_should_skip_remaining_attemptsr    s         r;   r   c                     | d S t          | t                    r|                     |          S t          | |d           }|j        j                            d          rd S |S )Nunittest.mock)r   r   rA   r   	__class__
__module__r  )objr   r   s      r&   _safe_obj_valuer    sf    
{t#t wws||Cd##E !,,_== tLr;   c                     | dS | j         j                            d          rdS t          | pd                                          S )Nr1   r  )r  r  r  r7   rm   )r   s    r&   _safe_text_valuer    sJ    }r!,,_== ru{!!###r;   r  r  c                &   |rdnd}	 t          | d          pg }|r|d         nd}t          |d          }t          t          |d                    }|r|dfS t          t          |d                                                    }t          t          |d	                    p9t          t          |d
                    pt          t          |d                    }|rdd| fS |dk    rdd| fS dd| fS # t          $ r
 dd| fcY S w xY w)zBReturn (content, empty_status) from an OpenAI-compatible response._auxr1   choicesr   Nrh   r   finish_reason	reasoningreasoning_contentthinkingr  lengthr  	llm_empty)r  r  r8   rC   )	respr  suffixr  choicerh   r   r  r  s	            r&   _extract_title_responser    sm   "VVF(!$	228b&0D!&)44"?7I#F#FGG 	B;()Q)QRRXXZZ_WkBBCC F9L M MNNF D DEE 	  	65V5555H$$,F,,,,'v'''' ( ( ('v''''''(s%   AC< BC< (C< 5C< <DDc                 n   | r|sdS t          | |          \  }}t          |||          }dddii}t          |||          rd|d<   	 t                      }	ddlm}
 d	}t          |          D ]\  }}d
|dd|dg}|g}	 t          |          D ]\  }} |
d|pd|pd|pd||d|	|	  	        }t          |d          \  }}|r||dk    r|dk    rdndfc c S |pd}|dk    r3t          |          r$|	                    t          |||                     n8# t          $ r+}d	}t                              d|dz   |           Y d}~nd}~ww xY wt          |          rt                              d|            nd|fS # t          $ r&}t                              d|           Y d}~dS d}~ww xY w)z2Return (raw_text, status) via auxiliary LLM route.Nmissing_exchanger  enabledFTreasoning_splitr   )call_llmllm_error_auxsystemr   r   rl  r  Ng?)	taskr   r   r  rp  
max_tokenstemperaturer@   
extra_bodyr  llm_auxllm_aux_retryllm_empty_auxz*Aux title generation attempt %s failed: %sr   zIAux title generation short-circuiting after %s (reasoning-only response).zAux title generation failed: %s)Nr  )r  r  r  r  r  r  	enumerater  r  r   r  rC   r  r  r  )rq  r  r   r   r  r  r  base_max_tokensreasoning_extra_timeoutr  last_statusidxpromptrp  budgets
budget_idxr  r  rE   empty_statuses                         r&   generate_title_raw_via_auxr    s     (N ('' N;;KB.xIIO"Y$67O5(33 2-1)*,%%''333333%$W-- $	 $	KC!f55B//H ''GW.7.@.@ b b*J
#8/!)!1T#mt!)!1T!)#-$' (#2
 
 
D )@$(O(O(O%C e"#((zQYYTcdddddd"."A/K!Q+>{+K+K'EhPUW_'`'`aaa#b$  W W W-I3QR7TUVVVVVVVVW 5[AA _    [   % % %6:::$$$$$$%sO   8F ADF >DF 
E$!E
F 
E4F 
F4F//F4c                    |r|sdS | dS t          ||          \  }}t          t          | dd          t          | dd          t          | dd                    }dd	i}t          | d
d          }	 || _        t	          |          D ]\  }}	d|	dd|dg}
|g}	 d}t	          |          D ]\  }}d}d}t          | dd          dk    rt|                     |
          }|                    dd           d|v r||d<   |                     |          }|                     |          \  }}|r	|j	        pdnd}|sd}nt          | dd          dk    rddl
m}m}  || j        |
d||t          | dd	          |                                 t          | dd                    }|                     |          } ||t          | dd	                    \  }}|r	|j	        pdnd}|sd}n|                     |
          }|                    dd           d|d<   d|d<   t!          t          | dd          t          | dd          t          | dd                    r.t#          |                    d          pi           }d|d <   ||d<   d!|v r||d!<   n||d"<    |                     d#$          j        j        j        d-i |}t/          |          \  }}t1          |pd                                          }|r||dk    r|dk    rd%nd&fc c || _        S |pd}|dk    r`t5          |          rQ|                    t9          t          | dd          t          | dd          t          | dd                               nX# t:          $ rK}d'}t<                              d(|d)z   t          | dd          t          | dd          |           Y d}~nd}~ww xY wtA          |          rt<                              d*|            nd|f|| _        S # t:          $ r-}t<                              d+|           Y d}~|| _        d,S d}~ww xY w# || _        w xY w).z1Return (raw_text, status) via active-agent route.r  N)Nmissing_agentr   r1   r   r  r  Freasoning_configr  r  rl  r  api_modecodex_responsestoolsmax_output_tokensanthropic_messagesr   )build_anthropic_kwargsnormalize_anthropic_response_is_anthropic_oauth_anthropic_base_url)r   rp  r  r  r  is_oauthpreserve_dotsr  )strip_tool_prefix皙?r  r  r@   r  Tr  max_completion_tokensr  r  )r   llm	llm_retry	llm_errorzGAgent title generation attempt %s failed: provider=%s model=%s error=%sr   zKAgent title generation short-circuiting after %s (reasoning-only response).z!Agent title generation failed: %s)Nr  r   )!r  r  r   r  r  _build_api_kwargspop_run_codex_stream_normalize_codex_responser   agent.anthropic_adapterr  r  r   _anthropic_preserve_dots_anthropic_messages_creater  r   rA   _ensure_primary_openai_clientchatcompletionscreater  r7   rm   r  r   r  rC   r  r  r  )ry   rq  r  r  r  r  disabled_reasoningprev_reasoningr  r  api_messagesr  r  r  r  rE   r  codex_kwargsr  assistant_message_r  r  
ant_kwargs
api_kwargsr  r  s                              r&   generate_title_raw_via_agentr  
  s    (N (''}$$ N;;KB.z2&&w##z2&& O
 $U+U$6==N\0!3$W-- T	 T	KC!f55B//L ''GE).7.@.@ : :*J
C#%Luj"559JJJ','>'>|'L'L$(($777.,>>@JL)<=$66|DD/4/N/Nt/T/T,)1CT\08>BZ\" 7+6L 
B77;OOOpppppppp%;%;"'+%1"&'1-?%,U4I5%Q%Q*/*H*H*J*J%,U4I4%P%P	& 	& 	&
  %??
KK/K/K GECXZ_4`4`0 0 0,)1 DU\08>BZ\" 7+6L%*%<%<\%J%J
"w55547
=104
9-,WUJ-K-KWUZ\cegMhMhjqrw  zD  FH  kI  kI  J  J B)-jnn\.J.J.Pb)Q)QJ<@J'897AJ|42j@@BLJ'>??7AJ|4uuBBJ\B]]bnu    (    -DD,I,I)\ciR....00C ]"cQhh:??UUP[\\\\\> "0= #/"=+K!Q+>{+K+K'E#E:r::#E7B77#E:r::( (   m:v    )]!GE:t44E7D11        5[AA a    [ 
 "0	  ! ! !8!<<<    !/	! "0////sc   2)P I4NP A,NP 
OAOP O4P 
Q"Q
=Q 
QQ 	Qc                     t          | ||          \  }}|sd|dfS t          |          }|r||dfS ddt          |          dd         fS )zGGenerate a title via active-agent route, then sanitize/validate result.Nr1   llm_invalidr<   )r  rS  r7   )ry   rq  r  rE   r   titles         r&   %_generate_llm_session_title_for_agentr  x  si    .uiPPKC  VR%c**E !fb  C#..r;   )use_agent_modelr  c                   |r6|r4t          |dd          }t          |dd          }t          |dd          }nd}d}d}t          | ||||          \  }}|sd|dfS t          |          }	|	r|	|dfS ddt          |          dd         fS )	a  Generate a title via dedicated auxiliary LLM route, then sanitize/validate result.

    When use_agent_model is False (default), the auxiliary client resolves
    provider/model/base_url from config.yaml auxiliary.title_generation, which
    prevents the session's chat model (e.g. a Chinese model) from overriding
    the dedicated title model.  When True, the agent's attrs are passed through
    (legacy fallback behaviour).
    r   r1   r   r  r  Nllm_invalid_auxr<   )r   r  rS  r7   )
rq  r  ry   r  r   r   r  rE   r   r  s
             r&   #_generate_llm_session_title_via_auxr    s      5 5*b11w++5*b11,  KC   VR%c**E !fb  "CHHTcTN22r;   r   r  raw_previewc           
          ||d}|r||d<   |r||d<   |r||d<    | d|           t                               d|||pd|pd|pdd d	                    d S )
N)r   r   r   r  r  title_statuszCtitle_status session=%s status=%s reason=%s title=%r raw_preview=%r-r1   r<   )r  info)	put_eventr   r   r   r  r  rr   s          r&   _put_title_statusr    s    '6::G #" !  -!,Ing&&&
KKM#		DSD!    r;   c                 z   | pd                                 } t          |pd                                           }| sdS t          |           } t          j        dd|                                            } t          j        dd|                                           }|  d|                                                                  |  d|                                  }dt          dt          fd}dt          dt          fd} ||          }|r ||          s<t          fd	d
D                       rdS t          fddD                       rdS dS t          fdd
D                       r| dS t          fddD                       r| dS | dS t          fddD                       r:t          fddD                       rt          fddD                       rdS dS t          fddD                       rt          fdd D                       rd!S t          fd"d#D                       rt          fd$d%D                       rd&S t          j	        d'|           d(                                          }|sdS h d)}d*}t          j
        d+| d,| d-|          }	|	sdS g }
|	D ]\}|                                }||v st          |          d.k     r.||
vr|
                    |           t          |
          d/k    r n]|
rd                    |
          dd0         S dS )1zIGenerate a readable local fallback title when LLM title generation fails.r1   Nr>  r;  r   r/   c                 J    t          t          j        d| pd                    S )Nz[A-Za-z]r1   )r   r?  rU  )r   s    r&   _contains_latinz6_fallback_title_from_exchange.<locals>._contains_latin  s     BIk4:266777r;   c                    t          j        d|           }|r)|                    d          pd                                S t          j        d|           }|r)|                    d          pd                                S dS )Nz"([^"\n]{2,24})"r   r1   u   “([^”\n]{2,24})”)r?  rU  grouprm   )r   rs  s     r&   _extract_named_topicz;_fallback_title_from_exchange.<locals>._extract_named_topic  s}    I)400 	.GGAJJ$"++---I/66 	.GGAJJ$"++---rr;   c              3       K   | ]}|v V  	d S r   r   r{   r   combineds     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      ||Q1=||||||r;   )timeschedule
efficiencymanagefitnesssingingcalligraphyzTime management discussionc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      DDQ1=DDDDDDr;   )rx   codexaizAI productivity discussionzConversation topicc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      xxqH}xxxxxxr;   z time managementc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      @@qH}@@@@@@r;   z AI productivityz discussionc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      
=
=Q1=
=
=
=
=
=
=r;   )r  zsession titlec              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  sH        FC  FCXYa8m  FC  FC  FC  FC  FC  FCr;   )summarysummarzshort titlec              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      AAqH}AAAAAAr;   )testokzreply okzSession title auto-summary testzSession title auto-summaryc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      
?
?Q1=
?
?
?
?
?
?r;   )r?   clarificationc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s(      GrGrZ[XGrGrGrGrGrGrr;   )dialogcardzClarify dialog cardc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s'      
<
<Q1=
<
<
<
<
<
<r;   )issuegithubprc              3       K   | ]}|v V  	d S r   r   r"  s     r&   r   z0_fallback_title_from_exchange.<locals>.<genexpr>  s(      DxDxWXQ(]DxDxDxDxDxDxr;   )triagebugreviewzGitHub Issue Triagez[.!?\n]r   >   thefromhereintojustneedr5  thatthisrl  wantwithaboutcouldneedsreplytherer  wantswouldpleaseshouldr2  testingrm  u   A-Za-z0-9À-ÖØ-öø-ÿ[z][z_./+-]*      <   )rm   rF  rj  r?  r@  r8   r7   r   r   r  findallrn   r   r   )rq  r  combined_rawr  r   
topic_namer  stop_en
latin_wordtokenspickedtok	lower_tokr#  s                @r&   _fallback_title_from_exchangere    s   b''))I+N,@bAAGGIIN t'	22IvsI..4466IVFC88>>@@N..n..4466<<>>H22.2288::L8c 8d 8 8 8 83 3     &%l33J *z** 	(||||*{||||| 433DDDD*CDDDDD 433''xxxx&wxxxxx 	3 2222@@@@&?@@@@@ 	3 2222))))

=
=
=
="<
=
=
=== ,#  FC  FC  FC  FC  ^B  FC  FC  FC  CC  CC ,AAAA&@AAAAA 	544++

?
?
?
?">
?
?
??? %CGrGrGrGr_qGrGrGrDrDr %$$

<
<
<
<";
<
<
<<< %DxDxDxDx\wDxDxDxAxAx %$$8J	**1-3355D t  G -JZ>Z>>:>>>EEF $##F  IIKK	3y>>A#5#5fMM#v;;!E   %xx$$r;   c                 p    t          | pd                                                                          dv S )zMReturn True for low-information fallback labels that should not be persisted.r1   >   conversation topicr7   rm   r8   )r  s    r&   _is_generic_fallback_titleri    s2    u{!!##))++/EEEr;   placeholder_titlec           	      *   	 	 t          |           }n1# t          $ r$ t          || dd           Y  |dd| i           dS w xY wt          |j                  }t          |dd          r:|s8t          || ddt          |j        pd	                     	  |dd| i           dS t          |j        pd	                                          }||k    p|d
v pt          ||j	                  p|}	|	s$t          || dd|           	  |dd| i           dS t                      }
|r5|
s3t          |||          \  }}}|s|dv rt          |||d          \  }}}n1t          ||          \  }}}|s|r|dv rt          |||          \  }}}|}|s]t          ||          }|r.t          |          st                              d           |}d}n|rt                              d|           |dk    r|rd| nd}d}|}|rt#          |           5  t$          5  t'          j        | |          }t          |j        pd	                                          }t          |j                  }||k    p|d
v pt          ||j	                  p|}	ddd           n# 1 swxY w Y   |	s/t          || dd|           	 ddd            |dd| i           dS ||k    r-||_        d|_        |                    d           |j        }d}ddd           n# 1 swxY w Y   |r?|dk    rt          || ||||           nt          || ||||            |d| |d           nt          || d|pd||            |dd| i           dS #  |dd| i           w xY w)zFGenerate and publish a better title after `done`, then end the stream.skippedmissing_session
stream_endr   Nllm_title_generatedFalready_generatedr1   )UntitledNew Chatr1   manual_titler  r  Try   r  r  r  z1Using local fallback for session title generationfallbackz@Skipping generic local fallback for session title generation: %rzlocal_summary:local_summarytouch_updated_atr  r   r  	unchanged)r   KeyErrorr  rR  r  r   r7   rm   r  rp  r  r  r  re  ri  r  r  r   r   r   rA   ro  save)r   rq  r  rj  r  ry   rE  _invalid_existingr  
still_autoaux_title_configured
next_title
llm_statusr  sourcefallback_titlefallback_reasonwrote_titleeffective_titleinvalid_existing_nows                       r&   _run_background_title_updater    s   N<	J''AA 	 	 	iY@QRRRR 		,z :;;;;;W	 ;17CC1+U33 	<M 	iY@SUXYZY`YfdfUgUghhhH 		,z :;;;;;G agm$$**,,(( !66!$Waj99! !	 	  	iYPWXXXt 		,z :;;;;;s  566 	~- 	~2WX]_hjx2y2y/J
K X*0L"L"L6YZces  |A  SW  7X  7X  7X3
J2UV_ao2p2p/J
K ~% ~J:^,^,^6[\acln|6}6}3
J 	q:9nUUN q&@&P&P qPQQQ+
# q_aoppp ##
# *Z)))  	
 ! 	'(44 ' ' 	 	 Z33A&)!'-R&8&8&>&>&@&@O+I!'+R+R('+<< 0*.JJ00!*MM0 0	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 " %iYXghhh' ' ' ' ' '> 		,z :;;;;;# 00(AG,0A)FFEF222&'gO"&K)' ' ' ' ' ' ' ' ' ' ' ' ' ' ',  	u##!)ZRacnoooo!)Z_^ijjjIgj?SSTTTTiY@U+Wfhsttt	,z :;;;;;		,z :;;;;s    N AN  AAN #AN C<N LA3J	LJ	LJ	L6N 3LN LN LAN Nc                    	 	 t          |           }n# t          $ r Y dS w xY wt          |j        pd                                          }||k    rt          || dd|           dS |r|dv rdS t                      }|r5|s3t          |||          \  }	}
}|	s|
dv rt          |||d          \  }	}
}n1t          ||          \  }	}
}|	s|r|
d	v rt          |||          \  }	}
}|	st          || d
|
pd||           dS t          j
        dd|                                                                          }t          j
        dd|	                                                                          }||k    rt          || d
d||           dS t          |           5  t          5  t          j        | |          }t          |j        pd                                          |k    rRt          || ddt          |j        pd                                                     	 ddd           ddd           dS |	|_        d|_        |j        }ddd           n# 1 swxY w Y   |                    d           ddd           n# 1 swxY w Y   t          || d|
||            |d| |d           t$                              d| |           dS # t(          $ r! t$                              d| d           Y dS w xY w)uR  Refresh an existing LLM-generated title using the latest exchange text.

    Unlike _run_background_title_update, this does NOT guard on
    llm_title_generated — it assumes the title was already LLM-generated
    and the session has progressed enough to warrant a refresh.
    It does NOT emit stream_end (the caller already did).
    Nr1   rl  rs  rq  rr  rt  Tru  rv  refresh_skippedemptyr>  r;  
same_titleFry  	refreshedr  r{  z/Adaptive title refresh: session=%s new_title=%rz.Background title refresh failed for session %sexc_info)r   r}  r7   r  rm   r  r  r  r  r?  r@  r8   r   r   r   rA   ro  r~  r  r  rC   r  )r   rq  r  r  r  ry   rE  	effectiver  r  r  r  normalized_currentnormalized_newr  s                  r&   _run_background_title_refreshr  ^  sR   1b	J''AA 	 	 	FF	 2&&,,..	%%iYPYZZZF 	I)AAAF466 	~- 	~2WX]_hjx2y2y/J
K X*0L"L"L6YZces  |A  SW  7X  7X  7X3
J2UV_ao2p2p/J
K ~% ~J:^,^,^6[\acln|6}6}3
J 	i5F
H]V]_hjuvvvFVFC;;AACCIIKKZ88>>@@FFHH//i5FV_almmmF$Z00 	+ 	+ * *LQ//qw}"%%++-->>%iYX[\]\c\igiXjXjXpXpXrXrsss* * * * * *	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ %(,%"#'* * * * * * * * * * * * * * * FFEF***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	)Zj/[fggg	'*OOPPPEzSbccccc b b bEz\`aaaaaabs    K 
!K !AK 'K /BK ?BK K J&A<I"J-K :IJI	J"I	#J<K JK JAK 'K?>K?c           	         t                      }|dk    rdS t          | j        pd                                          }|r|dv rdS t	          | dd          sdS t          | j                  }|dk    s	||z  dk    rdS t          | j                  \  }}|s|sdS t          j	        t          | j        |||||fd                                           dS )	zJCheck if the session is due for an adaptive title refresh and schedule it.r   Nr1   r  ro  FTtargetargsdaemon)r  r7   r  rm   r   r{  rp  rw  	threadingThreadr  r   start)sessionr  ry   refresh_intervalr  exchange_countlast_ulast_as           r&   _maybe_schedule_title_refreshr    s   2441+,,2244M M-EEE71599 %g&677Nn/??1DD.w/?@@NFF & , &&-ER   egggggr;   c                    t                      }| D ]}t          |t                    s|                    d          dk    rr|                    d          pg D ]Z}t          |t                    rC|                    d          p|                    d          pd}|r|                    |           [g }| D ]}t          |t                    s|                    d          r.|                    d          }|dk    r|                    d	          pd}|r||vrgd
 |                                D             }|                    d          r|                    |           |S )a  Return a deep copy of messages with only API-safe fields.

    The webui stores extra metadata on messages (attachments, timestamp, _ts)
    for display purposes. Some providers (e.g. Z.AI/GLM) reject unknown fields
    instead of ignoring them, causing HTTP 400 errors on subsequent messages.

    Also strips orphaned tool-role messages whose tool_call_id cannot be linked
    to a preceding assistant message with tool_calls. Strictly-conformant providers
    (Mercury-2/Inception, newer OpenAI models) reject histories containing dangling
    tool results with a 400 error: "Message has tool role, but there was no previous
    assistant message with a tool call."
    r   rm  r   idcall_idr1   _errortoolr   c                 ,    i | ]\  }}|t           v ||S r   _API_SAFE_MSG_KEYSr{   r   vs      r&   
<dictcomp>z._sanitize_messages_for_api.<locals>.<dictcomp>  )    MMMdaQ:L5L5LQ5L5L5Lr;   )setr   r   rA   addr  r   )rp  valid_tool_call_idsmsgtctidcleanr   	sanitizeds           r&   _sanitize_messages_for_apir    s     #uu 5 5#t$$ 	776??k))ggl++1r 5 5b$'' 5&&,,A"&&*;*;ArC 5+//444 E $ $#t$$ 	778 	wwv6>>''.))/RC #%888MMciikkMMM	==   	$LL###Lr;   c                    t                      }| D ]}t          |t                    s|                    d          dk    rr|                    d          pg D ]Z}t          |t                    rC|                    d          p|                    d          pd}|r|                    |           [g }t          |           D ]\  }}t          |t                    s|                    d          }|dk    r|                    d          pd}|r||vrTd	 |                                D             }|                    d          r|                    ||f           |S )
zCReturn [(original_index, sanitized_message)] for API-safe messages.r   rm  r   r  r  r1   r  r   c                 ,    i | ]\  }}|t           v ||S r   r  r  s      r&   r  z/_api_safe_message_positions.<locals>.<dictcomp>  r  r;   )r  r   r   rA   r  r  r  r   )	rp  r  r  r  r  outr  r   r  s	            r&   _api_safe_message_positionsr    s   "uu 5 5#t$$ 	776??k))ggl++1r 5 5b$'' 5&&,,A"&&*;*;ArC 5+//444
Ch'' 
) 
)S#t$$ 	wwv6>>''.))/RC #%888MMciikkMMM	==   	)JJY'(((Jr;   c                    | r|s|S t          |          }t          |           }d }d }d}|t          |          k     r||         \  }}| |         }|t          |          k     r||         nd}	t          |t                    rt          |	t                    r ||           ||	          k    r|                    d          dk    r5|                    d          r |	                    d          s|d         |	d<   |                    d          r!|	                    d          s|d         |	d<   nJ|                    d	          r5|	                    d	          s |	                    d          s|d	         |	d	<   |d
z  }\ ||          r/|                    |t          j        |                     |d
z  }|d
z  }|t          |          k     |S )ar  Carry forward display-only metadata lost during API-safe history sanitization.

    The provider-facing history strips WebUI-only fields like `reasoning`. When the
    agent returns its new full message history, prior assistant messages come back
    without that metadata unless we merge it back in by API-history position.

    This also preserves existing timestamps for unchanged historical messages.
    Without that, older turns that come back from the agent without `_ts` /
    `timestamp` can be re-stamped with the current time on every new assistant
    response, making prior messages appear to "move" in time.
    c                 r     t           t                    sd S  fd                                 D             S )Nc                 X    i | ]&\  }}|t           v                     d           #||'S )r   )r  rA   )r{   r   r  r  s      r&   r  zI_restore_reasoning_metadata.<locals>._safe_projection.<locals>.<dictcomp>  s:    \\\A5G0G0GCGGTZOO0G10G0G0Gr;   )r   r   r  r  s   `r&   _safe_projectionz5_restore_reasoning_metadata.<locals>._safe_projection  s<    #t$$ 	4\\\\\\\\r;   c                     t          | t                    r.|                     d          dk    s|                     d          sdS |                     d          rdS t          |                     d                     S )Nr   rm  r  Fr   r   )r   r   rA   rZ  r  s    r&   _reasoning_only_assistantz>_restore_reasoning_metadata.<locals>._reasoning_only_assistant  su    #t$$ 	;(F(FcggVaNbNb(F577<   	5 !3!34444r;   r   Nr   rm  r  r   _tsr   )	r   r  rn   r   r   rA   insertcopydeepcopy)
previous_messagesupdated_messages	prev_safer  r  safe_posprev_idxr  prev_msgcur_msgs
             r&   _restore_reasoning_metadatar    s/      $4  ,--+,=>>I] ] ]
5 5 5 H
S^^
#
#)!$X.083?O;P;P0P0P"8,,VZh%% 	*Wd*C*C 	HXHXYaHbHbfvfvw~ffHH||F##{22x||K7P7P2Y`YdYdepYqYq2'/'<$||K(( 1[1I1I 1'/'<$$e$$ 1W[[-?-? 1T_H`H` 1!)%MH$$X.. 	##HdmH.E.EFFFMHA) S^^
#
#* r;   c                 h    t          | dd          }t          |t                    r|r|S | j        pg S )zJReturn model-facing history without assuming it matches the UI transcript.context_messagesN)r   r   r   rp  )r  r  s     r&   _session_context_messagesr  1  sD    w(:DAA"D))  .>  !r!r;   c                 h   t          | t                    sd S t          |                     d          pd          }|                     dd          }t	          |          }|dk    rt          |d          }|s,|                     d          s|                     d          sd S |d	                    t          |pd                                                    d d
         t          |                     d          pd          t          j	        |                     d          pg dd          fS )Nr   r1   r   rl  Trc  r   r   r;  rn  F)	sort_keysensure_ascii)
r   r   r7   rA   rZ  rj  r   r  jsondumps)r  r   r   r   s       r&   _message_identityr  9  s!   c4   tswwv$"%%Dggi$$G!!Dv~~
 'tDAAA // 8M8M tTZR&&(())$3$/CGGN##)r**
377<((.B$USSS	 r;   c                     t          | pg           t          |pg           k     rdS t          |pg           D ]0\  }}t          | pg |                   t          |          k    r dS 1dS )NFT)rn   r  r  )rp  prefixr  expecteds       r&   _messages_have_prefixr  O  s    
8>rS2....u"6<R00  Xhn"c2337H7R7RRR55 S4r;   c                     t          | t                    sdS t          |                     dd                                                    }d|v pd|v pd|v pd|v S )NFr   r1   zcontext compactionzcontext compressionzcontext was auto-compressedz9active task list was preserved across context compression)r   r   rZ  rA   r8   )r  r   s     r&   _is_context_compression_markerr  X  sz    c4   uB//006688D$ 	O D(	O(D0	O G$N	r;   @  raw_textr5   c                     t          | t                    sdS |                                 }|sdS t          j        dd|                                          }t          |          |k    r|d|dz
            d}|S )z8Normalize a text blob used in compression summary cards.Nr>  r;  r~   rk   )r   r7   rm   r?  r@  rn   )r  r5   txts      r&   _compact_summary_textr  d  s    h$$ t
..

C t
&c
"
"
(
(
*
*C
3xx%[uqy[!&&&Jr;   c                    t          | t                    sd S t          |                     d          pd          }|r|dk    rd S |                     dd          }t	          |          }t          |          dk    r
|d d         }|                     d          p|                     d          }|                     d          }t          |t                    rt          |          nd	}|s|s|sd S ||||d
S )Nr   r1   r  r      r  r   r2  r   )r   tsr   r2  )r   r   r7   rA   rZ  rn   r   )rh   r   r   r   r  r2  attach_counts          r&   _compression_anchor_message_keyr  q  s	   gt$$ tw{{6""(b))D 46>>tkk)R((G!!D
4yy3DSDz	U			7w{{;77B++m,,K'1+t'D'DK3{###!L  R tDNNNr;   c                     t          | pg           D ]P}t          |t                    st          |          s(t	          |                    d                    }|r|c S Qd S )Nr   )rv  r   r   r  rZ  rA   )rp  rs  r   s      r&   "_compression_summary_from_messagesr    sy    hn"%%  !T"" 	-a00 	QUU9--.. 	KKK	4r;   c                    d                     t          |pd                                                    }d }t          | pg           D ]\  }}t	          |t
                    r|                    d          dk    r4|}d                     t          t          |                    dd                    d                                                    }|r||v s||v r|c S |S )Nr;  r1   r   rl  r   Trc  )	r   r7   r  r  r   r   rA   rj  rZ  )rp  r   needlerw  r  r  r   s          r&   _find_current_user_turnr    s    XXc(.b))//1122FHhn"--  S#t$$ 	6(A(Axx#cggi4455#   egg	
 
  	v~~JJJOr;   c                     t          | pg           }|s|S t          d|d          }|r#t          |d                   |k    r
|dd         S |S )zEReturn model history without an eager-checkpointed current user turn.rl  r  N)r   r  )rp  r   historycurrent_user_keys       r&   ,_drop_checkpointed_current_user_from_contextr    si    8>r""G (&X)N)NOO -gbk::>NNNss|Nr;   c                 J    t          |          ot          | dd          |k    S )a/  Return True only while a worker still owns the session writeback.

    cancel_stream() intentionally clears ``active_stream_id`` early so the UI can
    accept a follow-up turn while the old worker is unwinding. That old worker
    must not later persist its stale result over the newer transcript.
    active_stream_idN)r   r   )r  	stream_ids     r&   _stream_writeback_is_currentr    s'     	??Vww0BDIIYVVr;   c                    t          | pg           } t          |pg           }t          |pg           }|s| S t          ||          r|t          |          d         }nHt          ||          }d |d||nt          |                   D             }|
||d         ng }||z   }| dd         }d |D             }	t	          d|d          t          fd|D                       }
t          |ot	          |d                   k              }|
s|st          d |D                       rud|d}d	}|t          |          k     rBt          ||                   r-|d
z  }|t          |          k     rt          ||                   -|d|         |gz   ||d         z   }|D ]'}t	          |          }|"|k    r|rt	          |d                   |k    r6|Jt          |t                    r5|
                    d          dk    r|rt	          |d                   |k    rt          |          r|||	v r|}|M|k    rGt          |t                    r2|
                    d          dk    rt          j        |          }||d<   |                    t          j        |                     ||	                    |           )|S )a  Keep UI transcript durable while allowing model context to compact.

    If Hermes Agent returns a normal append-only history, append that delta to
    the UI transcript. If the model/context history was compacted and no longer
    has the prior context as a prefix, keep the previous UI transcript and append
    only compaction marker messages plus the current user turn onward.
    Nc                 0    g | ]}t          |          |S r   )r  r{   rs  s     r&   r}   z>_merge_display_messages_after_agent_result.<locals>.<listcomp>  s6     
 
 
-a00

 
 
r;   c                 ,    h | ]}t          |          S r   r  r  s     r&   r   z=_merge_display_messages_after_agent_result.<locals>.<setcomp>  s!    111Qa  111r;   rl  r  c              3   >   K   | ]}t          |          k    V  d S r   r  )r{   rs  r  s     r&   r   z=_merge_display_messages_after_agent_result.<locals>.<genexpr>  sC       % %56! 00% % % % % %r;   r  c              3   n   K   | ]0}t          |t                    o|                    d           dv V  1dS )r   )rm  r  Nrz  r  s     r&   r   z=_merge_display_messages_after_agent_result.<locals>.<genexpr>  sU       
 
 q$JAEE&MM5J$J
 
 
 
 
 
r;   r   r   r   rm  r   )r   r  rn   r  r  r   r   r  r   r   rA   r  r  r   r  )previous_displayprevious_contextresult_messagesr   r   current_user_idxmarker_candidatesturn_candidatesmergedseencurrent_user_in_candidates!current_user_already_checkpointedcurrent_user_msg	insert_atr  r   display_msgr  s                    @r&   *_merge_display_messages_after_agent_resultr    s    ,233,233?0b11O  _.>?? 	9$S)9%:%:%;%;<

2?HMM
 
&'r<L<X(8(8^abq^r^r'rs
 
 
 AQ@\/*:*;*;<<bd&8
aaa F11&111D(&X)N)NOO!$ % % % %:D% % % " " )-D$VBZ004DD) )% 	$* 	%1 	%  
 

 
 
 
 
 	% %+x@@	#j//)).LZXaMb.c.c)NI #j//)).LZXaMb.c.c)

+/?.@@:ijjCYY
 ! !$$O''' (!&*--44 O3%% ;.. /!&*--44 )#.. 	3?sd{{?s&666:c4;P;P6UXU\U\]cUdUdhnUnUn-,,K%-K	"dmK00111?HHSMMMMr;   i  c                    |dk    rdS t          | pd          }	 t          | t                    r| nt          j        |          }t          |t                    rP|                    d          p+|                    d          p|                    d          p|}t          |          }n# t          $ r Y nw xY w|d|         S )zDExtract a bounded result preview from a stored tool message payload.r   r1   outputr   r_   N)r7   r   r   r  loadsrA   rC   )rE   r5   r   r8  previews        r&   _tool_result_snippetr    s    zzrsyb>>D d++AssD1A1AdD!! 	 hhx(([DHHX,>,>[$((7BSBS[W[Gw<<D   <s   BB, ,
B98B9r~   c                     i }t          | t                    s|S t          |                                           d|         D ]9\  }}t	          |          }|dd         t          |          dk    rdndz   ||<   :|S )z3Truncate tool args for compact session persistence.Nr<   ...r1   )r   r   r   r  r7   rn   )r  r5   r  r   r  rE  s         r&   _truncate_tool_argsr  $  s    
CdD!! 
TZZ\\""6E6* ; ;1FF4C4SVVc\\EEr:AJr;   msg_idxc                     t          |dz
  dd          D ]<}| |         }t          |t                    r|                    d          dk    r|c S =dS )zEFind the closest preceding assistant message index for a tool result.r   r  r   rm  )ranger   r   rA   )rp  r  r  r  s       r&   _nearest_assistant_msg_idxr  /  s_    Wq["b))  smc4   	SWWV__%C%CJJJ2r;   c                    g }i }i }i }g }t          | pg           D ]\  }}t          |t                    s|                    d          }	|	dk    r|                    dd          }
t          |
t                    r|
D ]}t          |t                    rh|                    d          dk    rO|                    dd          }|r7|                    dd          ||<   |                    d	i           ||<   |||<   |                    d
g           D ]}t          |t                    s|                    dd          p|                    dd          }|                    di           }|                    dd          }	 t          j        |                    dd          pd          }n# t          $ r i }Y nw xY w|r|r|||<   |||<   |||<   |	dk    r|                    d          p|                    dd          }|                    dd          }||dd}|r|                    |d          }|rh|dk    rb|                    |t          |          ||                    |d          t          |                    |i                     d           d|d<   |                    |           d |pg D             }|rt          |          D ]\  }}|                    d          r|t          |          k    r n||         }|                    |                    dd          t          |                    dd                    |                    dd          pdt          | |                    dd                    t          |                    di           d          d           |S )zTBuild persisted tool-call summaries from final messages plus live progress fallback.r   rm  r   r1   rW   tool_user  r   inputr   r  function	argumentsz{}r  r   tool_use_idF)r  rE   resolvedr  )r   snippetr  assistant_msg_idxr  Tr  c                     g | ]G}t          |t                    |                    d           ,|                    d           dk    E|HS )r   r?   rz  )r{   r  s     r&   r}   z5_extract_tool_calls_from_messages.<locals>.<listcomp>m  sR    |||2Jr44H4H|RVVTZ^^|`b`f`fgm`n`nr{`{`{B`{`{`{r;   rE   r  r  r  rZ  )r5   )r  r   r   rA   r   r  r  rC   r   r  r  rn   r  )rp  live_tool_callsr   pending_namespending_argspending_asst_idxtool_msg_sequencer  rs  r   r   partr  r  fnr   r  rE   seqliveseq_idxlive_tcs                         r&   !_extract_tool_calls_from_messagesr.  8  s8   JMLB// +* +*
!T"" 	uuV}};eeIr**G'4(( <# < <D!$-- <$((62B2Bj2P2P"hhtR00 <15&"1E1EM#.04"0E0EL-4;,S1eeL"-- 4 4!"d++ ffT2&&?"&&B*?*?VVJ++vvfb)):bff[$&?&?&G4HHDD    DDD 44 4)-M#&(,L%,3$S)4 V^^%%''C155+C+CC%%	2&&C%cuEEC 
+$((b11 +DFNN%% $#7#<#<"-=-A-A#r-J-J 3L4D4DS"4M4M N N' '    '+C
O$$S)))||//R|||D %&788 	 	LGSwwz"" #d))##7mGFF33/r0B0BCC{{5"--3%?#''R[]_J`J`%a%a+GKK,C,C1MMM      s   *F33GGc                     d| dt          j        |d           d}| j                            |                    d                     | j                                         dS )z+Write one SSE event to the response stream.zevent: z
data: F)r  z

zutf-8N)r  r  wfilewriteencodeflush)handlereventr8  rr   s       r&   _sser6    se    QQQtz$U'K'K'KQQQGMw//000Mr;   c           	      b   t          t          | dd          pd          }|sdS d                    |                                          }|rt	          t          t          | dd          pg           dd                   D ]}t          |t                    r|                    d          d	k    r1d                    t          |                    d
          pd                                                    }||k    r dS t          t          j
                              }t          | dd          }t          |t          t          f          r|dk    rt          |          }d	||dd}t          | dd          }|rt          |          |d<   | j                            |           dS )a  Persist the pending user prompt before clearing runtime stream state.

    Error paths often clear ``pending_user_message`` before appending an assistant
    error marker. In deferred session-save mode that pending field can be the
    only durable copy of the user's current turn, so clearing it makes the user
    bubble disappear on reload/reconcile. Return True when a recovered user turn
    was appended.
    pending_user_messageNr1   Fr;  rp  ir   rl  r   pending_started_atr   T)r   r   r   
_recoveredpending_attachmentsr2  )r7   r   r   r  rv  r   r   r   rA   rB   r$  r   rp  r   )	r  pending_textnormalized_pendingexistingexisting_textrecovered_tsr9  	recoveredr;  s	            r&   +_materialize_pending_user_turn_before_errorrB    s    ww(>EEKLLL u,"4"4"6"677  ggz4&H&H&NB!O!OPRPSPS!TUU 	 	Hh-- f1E1E1O1OHHSi)@)@)FB%G%G%M%M%O%OPPM 222uu 3ty{{##L *>EE$sEl33 /8JQ8N8N-..!	 I "'+@$GG =#'(;#<#<	- I&&&4r;   c           	         ddl m}m} 	 |t          v r!t          |                                         rdS  || j                  }|dz  d| j         dz  }||nt          j                    }|5   || ||d           ddd           dS # 1 swxY w Y   dS # t          $ r. t                              d	t          | d
d                     Y dS w xY w)zFinal-exit guard: if the stream exits with pending_user_message still set,
    sync messages from the core transcript or add an error marker.
    Called from the outer finally block of _run_agent_streaming.
    Must never raise.
    r   )_get_profile_home _apply_core_sync_or_error_markerNsessionssession_.jsonF)stream_id_for_recheckrequire_stream_deadz1_last_resort_sync_from_core failed for session %sr   ?)
api.modelsrD  rE  r   is_setprofiler   
contextlibnullcontextrC   r  	exceptionr   )r  r  
agent_lockrD  rE  r   	core_path	_lock_ctxs           r&   _last_resort_sync_from_corerU    sw    ONNNNNNN
 $$i)@)G)G)I)I$F((99 :-0T7;M0T0T0TT	","8JJj>T>V>V	 	 	,,&/$)	   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  
 
 
?G\3//	
 	
 	
 	
 	
 	

s:   (B :B .B>B BB BB 4CCc                    	 ddl m}m} ddlm}m}m} ddlm}  |            }	|	st          
                    d           dS |5  |                    |d           ddd           n# 1 swxY w Y    ||             |||           }
t                              d| |           |
S # t          $ r(}t                              d	| ||           Y d}~dS d}~ww xY w)
a  Try to silently refresh credentials after a 401/auth error (#1401).

    Returns a new ``(agent, rt_dict)`` tuple on success so the caller can
    retry the conversation.  Returns ``None`` when self-heal is not
    applicable (e.g. auth.json unchanged, provider unresolvable).

    Steps:
    1. Re-read ``~/.hermes/auth.json`` to pick up fresh credentials that
       may have been written by a concurrent ``hermes model`` CLI invocation.
    2. Evict the session's cached agent so it is rebuilt with fresh keys.
    3. Evict the provider's credential-pool cache entry.
    4. Re-resolve the runtime provider.
    5. Return a new agent + resolved-provider dict (the caller must
       re-invoke ``run_conversation`` with these).
    r   )read_auth_json0resolve_runtime_provider_with_anthropic_env_lock)SESSION_AGENT_CACHESESSION_AGENT_CACHE_LOCK invalidate_credential_pool_cacheresolve_runtime_providerz7[webui] self-heal: auth.json empty or missing, skippingN	requestedzJ[webui] self-heal: credential refresh succeeded for provider=%s session=%sz8[webui] self-heal: failed for provider=%s session=%s: %s)	api.oauthrW  rX  r  rY  rZ  r[  hermes_cli.runtime_providerr]  r  r  r  r  rC   warning)provider_idr   _agent_lock_refrW  rX  rY  rZ  r[  r]  _fresh_auth_new_rt	_heal_errs               r&   _attempt_credential_self_healrh    s   $(	
 	
 	
 	
 	
 	
 	
 	
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	IHHHHH %n&& 	LLRSSS4 & 	6 	6##J555	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	)(555 CB$!
 
 

 	X	
 	
 	
    FY	
 	
 	
 tttttsA   >B( B( A'B( 'A++B( .A+/8B( (
C2CC)	ephemeralmodel_providergoal_relatedc                ܓ    t          j                  dS t           t          j                    dt	          |          ||t          |                     |sS	 t           dt          j                    d           n,# t          $ r t          	                    dd           Y nw xY wdi }	d}
d}d}d}i }t          j                    t          5  t          <   d	t          <   d	t          <   g t           <   ddd           n# 1 swxY w Y   dd
gd
gt#                      dt$          f fddt$          ffd fdt'                                                     t          j                     fd}t          j        |d          }|                                 fd fd}dd}d	 t/                     t1          d            t	          t3          |                                                                                    _        |_        |3t	          |                                                                          ntA          dd          }|pd_!        tE                     #                                rY dddi           	                                  ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS 	 d
dl+m,}m-}m.}  |tA          d d                    }t	          |          } ||          }n4# t^          $ r' t`          j1                            d!d	          }i }d}Y nw xY wtA          d d          }|s$	 d
d"l+m2}  |            }n# t          $ r d}Y nw xY wtg          |t	          j                   |          }ti          di | tk                       tl          5  d# |D             }t`          j1                            d$          }
t`          j1                            d%          }t`          j1                            d&          }t`          j1                            d!          }t`          j1        7                    |           t	          j                  t`          j1        d$<   d't`          j1        d%<    t`          j1        d&<   |r)|t`          j1        d!<   | |t3          |                     ddd           n# 1 swxY w Y   	 d
d(l8m9}  |             n# t          $ r Y nw xY wd)}d}	 d
d*l:m;} m<} fd+}! |  |!           d}n*# t^          $ r t          	                    d,           Y nw xY wd)}"d}#	 d
d*l=m;}$m<}# fd-}% |$ |%           d}"n*# t^          $ r t          	                    d.           Y nw xY wd/ 	 d)d)}&d	g t          j>                    d0z
  gd
gd
g fd1fd2}'fd3}(fd4})d
gfd5fd6 f	d7}* fd8}+ fd9},t                      }-|-t_          t                                d}.	 d
d:lAmB}/  |/            }.n+# t          $ r}0t          d;|0 d<           Y d}0~0nd}0~0ww xY wt          t          ||                    \  }1}2}3d}4	 d
d=lFmG}5 d
d>lHmI}6  |5|6|2?          }	|	                    d@          }4|2s|	                    dA          }2|3s|	                    dB          }3n+# t          $ r}7t          dC|7 d<           Y d}7~7nd}7~7ww xY wt          |2t                    r3|2K                    dD          rt          |2          \  }8}9|4s|8r|8}4|3s|9r|9}3d
dElMmN}:  |:            };d
dFlMmO}<  |<|;          }=	 d
dGlPmQ}>mR}? |?  dHz  }@|@S                                r.|>T                               }A|ArtA          |AdId          nd}B|Br|B}=n.# t          $ r!}Ct          dJ  dK|C d<           Y d}C~Cnd}C~Cww xY w|;                    dL          p|;                    dM          pd}Dd}E|Drd}Ft          |Dt                    r4|DD ]0}Gt          |Gt                    r|G                    dN          r|G}F n1n,t          |Dt                    r|D                    dN          r|D}F|Fri|F                    dNd	          |F                    dAd	          |F                    dB          |F                    d@          |F                    dO          dP}Ed
dlW}Ht#          |HX                    |-jY                  jZ                  }Id}J	 d}Kt          |;t                    r|;                    dQi           ni }Lt          |Lt                    r|L                    dR          }K|K*t          |;t                    r|;                    dR          }K|Kt%          |K          }M|Md
k    r|M}Jn# t          $ r d}JY nw xY wd}N	 |;                    dS          }O|O@|;                    dQi           }Pt          |Pt                    r|P                    dS          }O|Ot%          |O          }Q|Qd
k    r|Q}Nn# t          $ r d}NY nw xY w	 d
dTlMm[}R t          |;t                    r|;                    dQi           ni }St          |St                    r|S                    dU          nd}T |R|T          }Un# t          $ r d}UY nw xY wt          |1|2|3|4dVd|=|E |.|'|(|* fdWX          }VdY|Iv r|U|U|VdY<   dZ|Iv r|)|VdZ<   d[|Iv r|+|Vd[<   d\|Iv r|,|Vd\<   d]|Iv r||Vd]<   d^|Iv r|J|J|Vd^<   dS|Iv r|N|N|VdS<   d_|Iv r|	                    d_          |Vd_<   d`|Iv r|	                    da          |Vd`<   db|Iv r|	                    dc          |Vdb<   dd|Iv r|	                    dd          |Vdd<   de|Iv r |Vde<   |r& |-di |Vt          	                    df            n'd
dl\}Wd
dl]}Xd
dglMm^}Ym_}Z |X`                    |1pd	|Wa                    |4pd	b                                          c                                ddh         |3pd	|2pd	|Jpd	|Npd	|Epi |=rt          |=          ng |Upi |pd	g
di          }[|Wa                    |[b                                          c                                ddh         }\d|Z5  |Y                               }]|]rD|]d0         |\k    r8|]d
         |Ye                                t          	                    dj            ddd           n# 1 swxY w Y   |V                    dk          _f        |V                    dl          _g        t          d[          r|V                    d[          _i        t          d\          r|V                    d\          _j        t          d]          r|V                    d]          _k        t          dZ          r|V                    dZ          _l        t          dm          r|V                    dm          _m        t          dn          r|V                    dn          _n        |.It          do          r2jo        +	 jo        p                                 n# t          $ r Y nw xY w|._o        t          dp          rd
_q        t          dq          rd)_r        t          dr          rd_s        n |-di |V|Z5  |\f|Y <   |Ye                                d
dslMmt}^ t          |Y          |^k    r|Yv                    d)t          \  }_}`	 t          |`t                    r|`d
         nd}a|a*tA          |adod          |ajo        p                                 n# t          $ r Y nw xY wt          	                    du|_           t          |Y          |^k    ddd           n# 1 swxY w Y   t          	                    dv            t          5  tP          <   t          v rt                   #                                rb	 x                    d           n*# t          $ r t          	                    dw           Y nw xY w dddxi           	 ddd                                            |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           n# 1 swxY w Y                                    ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS ddd           n# 1 swxY w Y   t          t	          j                            }dd{j         d|}ed}ftA          d}d          }g|gr$|;                    dQi           }h|h                    d~i           }it          |it                    r|g|iv r|i|g         }jt          |jt                    r|j                    dd	          p|j                    dd	          g}k|j                    d          r|k{                    d|jd                     |j                    d          r|k{                    d|jd                     d$                    d |kD                       }fnt	          |j          }f|fr|f_|        tA          dd          }l|lr|lnt          j                    }mt          j}        pg           }nt          t                    |          }otA          tA          dd          dd
          }pfd}qt          j                    5                      dd)           ddd           n# 1 swxY w Y   t          j        |qdd dd                    }|                                 t          |d||||;          }r                    |r|et          |o           |          }s|r
d	}tt	          |s                    d          pg           D ]U}ut          |ut                    r>|u                    d          dk    r%t	          |u                    dd	                    }t nV d |s                    dg           dd
d
dd|td                                            	 d
dl}v|v                    j                                      d           n# t          $ r Y nw xY w	                                  |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           n# 1 swxY w Y                                    ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS                                  ||$                    d           5  |s`t                    sNt                              dtA          d           tA          dd                     	 ddd                                            |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           n# 1 swxY w Y                                    ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS |s                    d          p|o}wt          |o|w          }x|x_        t          |n|ot          |n|w          |          _}        j}        D ]}ut          |ut                    r|u                    d          dk    r|u                    d          }yt          |yt                    rt          |y          }z|z|yk    r|z|ud<   vt          |yt                    r[|yD ]X}{t          |{t                    rAt          |{                    d          t                    rt          |{d                   |{d<   Yt          d |s                    d          pg D                       }|||sstA          dd          p|s                    d          pd	}}|}rt	          |}          nd	}~t          |~|}t          |~                     }|d         dk    }|d         dk    }|r|d         }|d         }|d         }n|r]|&sZd}t!          |2pd	           }|8t                              d           |}	|                    d@          }4|2s|                    dA          }2|3s|                    dB          }3t          |2t                    r3|2K                    dD          rt          |2          \  }8}9|4s|8r|8}4|3s|9r|9}3|4|Vd@<   |3|VdB<   |1|VdN<   |2|VdA<   dd|Iv r|                    dd          |Vdd<    |-di |Vt          5  tP          <   ddd           n# 1 swxY w Y   d
dglMm^}m_} |5  |\f| <   |e                                ddd           n# 1 swxY w Y   d}&d)	                     |r|et          |o           |          }t          d |                    d          pg D                       p}n4# t          $ r'}t                              d|           d)}Y d}~nd}~ww xY w|r\|Z|}s|s                    d          p|o}wt          |o|w          }x|x_        t          |n|ot          |n|w          |          _}        d}|||sd}d}d}n!|rd}d}d}n|d         }|d         }|d         }||rnt%          |~p| d||          } d|           t'                     d_        d_        g _        d_        dd| d|                    d          p| d| dt%          t          j                              dd}|                    d          r|d         |d<   j}        {                    |           	                                  n# t          $ r Y nw xY w	 ddd                                            |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           n# 1 swxY w Y                                    ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS tA          dd          }d)}|r| k    r{ }|}|?| dHz  }|?| dHz  }|_        j        s%|r#|_        t                              d||           t4          5  |t6          v rt7          j'        |          t6          |<   ddd           n# 1 swxY w Y   t8          5  t:          |<   t;          j'        |d           ddd           n# 1 swxY w Y   d
dglMm^}Ym_}Z |Z5  |Y'                    |d          }|r||Y|<   ddd           n# 1 swxY w Y   |S                                rV|S                                sB	 |                    |           n+# t>          $ r t          	                    d           Y nw xY wd}|s*tA          dd          }|rtA          |dd
          |pk    rd}|rtA          j}        d          }|r!tC          d
t          |          d0z
            nd_        |rtG          |d                   nd_        tK          tM          j}                  ptM          j                            _         dddi           t          j                    }j}        D ]S}ut          |ut                    r<|u                    d          s'|u                    d          st%          |          |ud<   Tj        dk    sj        dk    sj        s tS          j}        j                  _        j        dk    pj        dk    pj         }tU          j        j}                  }tW          j                  }|s|s|otA          dd)           p|}d	}d	}|rtY          j}                  \  }}tA          dd
          pd
}tA          dd
          pd
}tA          dd          }|d
k    r|_        |d
k    r|_        ||_        ta          j}        ¦          }|_        d_        d_        g _        d_        |rdÄ |D             }t	          j}                  D ]}|                    d          dk    rut	          |                    dd	                    }d|v r-|                    dŦ          d
                                         n|}|ddƅ         |v s|ddƅ         |v r||d<    nrTj}        rMt	          j}                  D ]7}t          |t                    r |                    d          dk    r|d<    n8	 tC          dt          j                    tg          |m          z
            }n# t          $ r d}Y nw xY wd}|r(|d
k    r"ti          tg          |          |z  d0          }tk          |s|1p||2ʦ          }|rK|_        t          tA          dd          pg           }|{                    |           |dd         _        j}        rjt	          j}                  D ]T}t          |t                    r=|                    d          dk    r$ti          |dͦ          |d<   |||d<   |r||d<    nUtA          dd          }|rHtA          |dd
          pd
_        tA          |dd
          pd
_        tA          |dd
          pd
_        tA          dd
          s	 d
dlm} d}d}	 t          |;t                    r|;                    dNi           ni }t          |t                    rI|                    dѦ          }|2	 t%          |          }|d
k    r|}n# tz          t|          f$ r Y nw xY wt          |;t                    r|;                    dզ          nd}t          |t                    r|}n# t          $ r Y nw xY w |tA          dN|1pd	          pd	tA          dBd	          pd	||2pd	|֦          }|r|_        nm# tz          $ rT 	 d
dlm}  |tA          dN|1pd	          pd	tA          dBd	          pd	          }|r|_        n# t          $ r Y nw xY wY nt          $ r Y nw xY w|sԉj}        r͐t          fdׄt          t          j}                  d0z
  dd          D             d          }|j}        |         }	 t          j        dؐtg          |                    d          pt          j                              |dٜ           n,# t          $ r t          	                    dd           Y nw xY w                                 |s	 t          j        dt          j                    t          fd܄t          t          j}                  d0z
  dd          D             d          dٜ           n,# t          $ r t          	                    dd           Y nw xY wddd           n# 1 swxY w Y   	 d
dlMm}  |                                dߦ          rGd
dlm}  |j        j        pd
j        pd
j        |j        t          j}                             n*# t          $ r t          	                    d           Y nw xY w|||ti          |dͦ          d}|||d<   |r||d<   tA          dd          }|rBtA          |dd
          pd
|d<   tA          |dd
          pd
|d<   tA          |dd
          pd
|d<   |                    dѦ          s|	 d
dlm} d}d}	 t          |;t                    r|;                    dNi           ni }t          |t                    rI|                    dѦ          }|2	 t%          |          }|d
k    r|}n# tz          t|          f$ r Y nw xY wt          |;t                    r|;                    dզ          nd}t          |t                    r|}n# t          $ r Y nw xY w	  |tA          dN|1pd	          pd	tA          dBd	          pd	||2pd	|֦          }nA# tz          $ r3  |tA          dN|1pd	          pd	tA          dBd	          pd	          }Y nw xY w|r||d<   n# t          $ r Y nw xY w|                    dӦ          stA          dd
          pd
}|r||d<   	 tA          dd          }|r
 |            nd}|r d t	          |          d           n+# t          $ r t          	                    d            Y nw xY w	 d
dlm}m} |r | |          si }n'd	}Ðt	          j}        pg           D ]}t          |t                    r|Ġ                    d          dk    r1|Ġ                    dd	          }t          |t                    rg }|D ]e}t          |t                    rN|Ǡ                    d          p|Ǡ                    d          }|r"|Ơ{                    t	          |Ȧ                     fd$                    |Ʀ          }nt	          |pd	          }  d dddd            | |d|          }|pi }t	          |ɠ                    d          pd	                                          }|rX d |ɠ                    d          rdnd||ɠ                    d          p|rdnd	|ɠ                    d          pg |d           |ɠ                    d          rt	          |ɠ                    d          pd	                                          }|rSt          j                     d ||||ɠ                    d          pd|ɠ                    d          pg |d           n3# t          $ r&}t          	                    d |̦           Y d}~nd}~ww xY w                                j}        |dz  } dt          |ͦ          |d           t'                                                      }Ή |d<   |Π                    dd)           |Π                    d d)            d|Φ           |rf|rd|rbt          j        t          j        ||t	          j        pd	                                          fd                                           n! dd i           t                                                      |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           n# 1 swxY w Y   n#                                  |r9|7	  |            n*# t          $ r t          	                    dy           Y nw xY w|"r9|#7	  |#            n*# t          $ r t          	                    dz           Y nw xY wtl          5  |y                                D ]7\  }b}c|c!t`          j1        '                    |bd           (|ct`          j1        |b<   8|
!t`          j1        '                    d$d           n|
t`          j1        d$<   |!t`          j1        '                    d%d           n|t`          j1        d%<   |!t`          j1        '                    d&d           n|t`          j1        d&<   |!t`          j1        '                    d!d           n|t`          j1        d!<   ddd           w # 1 swxY w Y   w xY w
n# t          $ 
rr}t          dt          j                    z   d<           t	          |Ϧ          }Аt          j        dd|Ц          }ѐt          j        dd|Ѧ                                          }||k    r|}|Р                                }Ґt          ||Ϧ          }|d         dk    }|d         dk    o| }|d         dk    }|d         d	k    }|r|d         |d         |d         }}}אn|r|d         |d         |d         }}}אn|Րr|&sÐt!          |2pd	           }|t                              d
           d}&|}	|                    d@          }4|2s|                    dA          }2|3s|                    dB          }3t          |2t                    r3|2K                    dD          rt          |2          \  }8}9|4s|8r|8}4|3s|9r|9}3dt                      v rt          |V          ni }|4|d@<   |3|dB<   |1|dN<   |2|dA<   dd|Iv r|                    dd          |dd<    |-di |ڤ}t          5  |tP          <   ddd           n# 1 swxY w Y   d
dglMm^}m_} |5  ||\f|܉ <   |ܠe                                ddd           n# 1 swxY w Y   d)	 |۠                    |r|et          |o           |          }u                                 ||$                    d           nt          j                    }|5  |st                    st                              dtA          d           tA          dd                     	 ddd           Y d}~ω                                 ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS |                    d          p|o}wt          |o|w          }x|x_        t          |n|ot          |n|w          |          _}                                         ddd           n# 1 swxY w Y   t                              d           Y d}~ω                                 ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS # t          $ r&}t                              d|ߦ           Y d}~nd}~ww xY wd\  }}}n"|r|d         |d         |d         }}}nd\  }}}ِt%          |||٦          }@                                 ||$                    d           nt          j                    }|5  |st                    st                              dtA          d           tA          dd                     	 ddd           Y d}~ω                                 ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS t'                     d_        d_        g _        d_        dd|כ d|                    d          p|Л |rd|ٛ dnd	z   t%          t          j                              dd}|                    d          r|d         |d<   j}        {                    |           	                                  n# t          $ r Y nw xY w|s\	 t          j        dt          j                    |ؐd           n-# t          $ r  t          	                    dd           Y nw xY wddd           n# 1 swxY w Y    d|           Y d}~nd}~ww xY w                                 ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           dS # 1 swxY w Y   dS #                                  ||$                    d           HtA          dd          k    r3tA          dd          r"t1          d           tK                     tM                       t          5  t          j'        d           t          j'        d           tQ          j'        d           t          j'        d           t          j'        d           t!          j'        d           tS          j'        d           tU                     ddd           w # 1 swxY w Y   w xY w(  u   Run agent in background thread, writing SSE events to STREAMS[stream_id].

    When ephemeral=True, session mutations are skipped — used by /btw to get
    a streaming answer without persisting to the parent session.
    Nstarting)r   
started_atphaser   r   r   ri  worker_started)r5  
created_atz2Failed to append worker_started turn journal eventTr  r1   r   r/   c                  j   d         dk    rd         S d} }|:	 t          |dd          }|rt          |dd          pd} n# t          $ r d} Y nw xY w| s6	 t                    }t          |dd          pd} n# t          $ r d} Y nw xY wt          | pd          d<   d         d<   d         S )zDCapture the latest exact prompt size before adding live tool deltas.r   Ncontext_compressorlast_prompt_tokens)r   rC   r   rB   )_base_agent_cc_session_obj_live_prompt_estimate_tokens_live_prompt_exact_tokensry   r   s       r&   _seed_live_prompt_estimatez8_run_agent_streaming.<locals>._seed_live_prompt_estimateI  s   '*Q../22f&:DAA G#C)=qAAFQE    	*:66.BAFFK!   *-ejq//$Q''CA'F!!$+A..s#   &A AA"A< <B
Bc                     | sd         S 	 ddl m} t           ||           pd          }n# t          $ r d}Y nw xY w|dk    r              dxx         |z  cc<   d         S )z?Increment a rough next-prompt estimate from live tool activity.r   )estimate_messages_tokens_rough)agent.model_metadatar}  rB   rC   )rp  r}  _deltary  r{  s      r&   _bump_live_prompt_estimatez8_run_agent_streaming.<locals>._bump_live_prompt_estimate`  s     	3/22	KKKKKK77AAFQGGFF 	 	 	FFF	A::&&((((+++v5++++A..s    . ==c                     ddddddd} 	 t          	          }n# t          $ r d}Y nw xY w}|	 t          |dd          pd| d<   t          |dd          pd| d<   t          |dd          pd| d	<   n# t          $ r Y nw xY w	 t          |d
d          }|rBt          |dd          pd| d<   t          |dd          pd| d<   t          |dd          pd| d<   n# t          $ r Y nw xY w|BdD ]?}|                     |          s(	 t          ||d          pd| |<   /# t          $ r Y ;w xY w@t	          |                     d          pd          }|r|d         k    r|d<   |d<   nd         |k    rd         | d<   | S )a}  Best-effort live usage payload for mid-stream UI updates.

        During tool execution the final `done` event has not fired yet, but the
        frontend still benefits from seeing the latest known token / context
        values. These are exact for the most recent model call and a truthful
        lower bound for the pending next call after a tool result is appended.
        r   )input_tokensoutput_tokensestimated_costcontext_lengththreshold_tokensrt  Nsession_prompt_tokensr  session_completion_tokensr  session_estimated_cost_usdr  rs  r  r  rt  )r   rC   r   rA   rB   )
_usagerx  rv  rw  _field_real_prompt_tokensry  rz  ry   r   s
         r&   _live_usage_snapshotz2_run_agent_streaming.<locals>._live_usage_snapshotn  sx     !"#
 
	 &z22LL 	  	  	 LLL	  )09PRS)T)T)YXY~&*1&:UWX*Y*Y*^]^'+26;WYZ+[+[+`_`'((   f&:DAA ^/6s<La/P/P/UTUF+,18>PRS1T1T1YXYF-.3:3@TVW3X3X3]\]F/0    # J  zz&)) )0vq)I)I)NQv$    "&**-A"B"B"GaHH 	K#6:STU:V#V#V+>%a(.A(++)!,/BBB+G+JF'(sC    ++AA6 6
BBAC 
C*)C*	D  
D-,D-c                     	 t                                                      } | dk    rd S                     |           rd S t                                                      }|d<                |d<    d|           ~)NTg      $@r   r   metering)r    get_intervalwait	get_stats)intervalstatsr  _metering_stopputr   s     r&   _metering_tickerz._run_agent_streaming.<locals>._metering_ticker  s    		#ww++--H4""8,, GG%%''E",E,1133E'NC
E"""		#r;   )r  r  c                                                      r| dvrd S 	                     | |f           d S # t          $ r t                              d           Y d S w xY w)N)cancelr_   zFailed to put event to queue)rM  
put_nowaitrC   r  r  )r5  r8  cancel_eventqs     r&   r  z!_run_agent_streaming.<locals>.put  s       	U2E%E%EF	9LL%''''' 	9 	9 	9LL7888888	9s   6 $AAc                 :   t          |pd                                          }t          | pd                                                                          }|sdS |                                }|dk    od|v pd|v pd|v pd|v }|sdS  ddd	           dS )
z9Bridge Agent lifecycle compression status into WebUI SSE.r1   N	lifecyclezpreflight compressioncompressingzcompacting contextzcontext too largez'Auto-compressing context to continue...)r   rh   rh  )kindrh   rp   _kind_lower_is_compression_startr  r   s         r&   _agent_status_callbackz4_run_agent_streaming.<locals>._agent_status_callback  s    w}"%%++--DJB%%''--// 	F!![  '61 1 F*1'611 '&0 	 % 	FM$@
 
 	 	 	 	 	r;   running)ro  r   rj  r  rh   zCancelled before start   r@   r  r8  
finalizing)ro  )patch_skill_home_modulesget_hermes_home_for_profileget_profile_runtime_envrN  r   )get_active_profile_namec                 N    i | ]"}|t           j                            |          #S r   )r   r   rA   )r{   r   s     r&   r  z(_run_agent_streaming.<locals>.<dictcomp>(	  s(    XXXCsBJNN3$7$7XXXr;   r   r   r   r   )discover_mcp_toolsF)register_gateway_notifyunregister_gateway_notifyc                       d|            d S )Napprovalr   )approval_datar  s    r&   _approval_notify_cbz1_run_agent_streaming.<locals>._approval_notify_cb_	  s    J.....r;   z6Approval module not available, falling back to pollingc                       d|            d S )Nr?   r   )clarify_datar  s    r&   _clarify_notify_cbz0_run_agent_streaming.<locals>._clarify_notify_cbn	  s    I|,,,,,r;   z5Clarify module not available, falling back to pollingc                 N   t                      }d |pg D             }t          | pd          ||dt          j                    |d}	 ddlm}m}	 n# t          $ r 	 Y dS w xY w |||          }
t          j                    |z   }	 |                                r |	|           	 dS |t          j                    z
  }|dk    r |	|           	 dS |
j	        
                    t          d	|          
          r,t          |
j        pd                                          }|pdS )z+Bridge Hermes clarify prompts to the WebUI.c                 ,    g | ]}t          |          S r   )r7   )r{   r  s     r&   r}   zH_run_agent_streaming.<locals>._clarify_callback_impl.<locals>.<listcomp>y	  s    FFFFCKKFFFr;   r1   r?   )questionchoices_offeredr   r  requested_atrF   r   )submit_pendingclear_pendingzrThe user did not provide a response within the time limit. Use your best judgement to make the choice and proceed.Tg      ?r  )rG   r7   r$  api.clarifyr  r  r$   	monotonicrM  r5  r  minr   rm   )r  r  sid
cancel_evtr  r@   choices_listr8  _submit_clarify_pending_clear_clarify_pendingr   deadline	remainingresponses                 r&   _clarify_callback_implz4_run_agent_streaming.<locals>._clarify_callback_implv	  s   .00GFFw}"FFFLB//#/!! $	#* Dzzzzzzzzz   N   ,+C66E~'''1H$$&& **3///R  %t~'7'77	>>**3///R  ;##CY,?,?#@@ "5<#5266<<>>H  UU!s   A AAr   c                  .   t          j                    } | d         z
  dk     rd S | d<   t                                                      }|d<                |d<   |                    dd           |                    dd            d|           d S )	Nr   r  r   r   tps_availableF	estimatedr  )r$  r  r    r  
setdefault)nowr  r  _metering_last_emitr  r   s     r&   _emit_meteringz,_run_agent_streaming.<locals>._emit_metering	  s    n&&,Q//#55F),#A&))++&0l#!5!5!7!7g  %888  e444J&&&&&r;   c                 
   | d S dt           v r"t           xx         t          |           z  cc<    dd| i           dxx         dz  cc<   t                                          d                                  d S )NTtokenr   r   r   )r
   r7   r    record_token)r   r  _metering_output_deltas_token_sentr  r  s    r&   on_tokenz&_run_agent_streaming.<locals>.on_token	  s    <F" 333'	222c$ii?222Gfd^,,, (***a/***$$Y0G0JKKK     r;   c                 D   | d S t          |           z  t          v r"t          xx         t          |           z  cc<    ddt          |           i           dxx         dz  cc<   t                                          d                                  d S )Nr  r   r   r   )r7   r   r    record_reasoning)r   r  _metering_reasoning_deltas_reasoning_textr  r  s    r&   on_reasoningz*_run_agent_streaming.<locals>.on_reasoning	  s    <F3t99, 555))444D		A444K&#d))!4555*1---2---((4Nq4QRRR     r;   c           
          | d S t          |                                           }|sd S  d|t          |                    dd                    d           d S )Ninterim_assistantalready_streamedF)r   r  )r7   rm   r   rA   )r   	cb_kwargsvisibler  s      r&   on_interim_assistantz2_run_agent_streaming.<locals>.on_interim_assistant	  sw    <Fd))//++ F'#(,Y]];Mu-U-U(V(V* *     r;   c           	          | r| v rd S                      |            | dt          |pd          t          j        t	          |t
                    r|ni dd          dd} dd|gd	g           d S )
Nr  r1   FT)r  r  )r   r  )r  rW   r  rm  )r   r   r   )r  r7   r  r  r   r   )r   r   r  
_tool_callr  _live_prompt_estimate_seen_idss       r&   _record_live_tool_startz5_run_agent_streaming.<locals>._record_live_tool_start	  s    # |7U'U'UF.22<@@@&& #DJB%)Z
48N8N0VTVejvz%{%{%{! ! 
 +*'!#-,- - ,     r;   c                 n    | sd S t          |          } dt          |pd          | |dg           d S )Nr  r1   )r   r   r   r   )r  r7   )r   r   function_result_result_textr  s       r&   _record_live_tool_completez8_run_agent_streaming.<locals>._record_live_tool_complete	  sa    # F3ODD**"
OO$0+	- - ,     r;   c                  L	  	 d }d }d }d }t          |           dk    r| d d         \  }}}}nRt          |           dk    r	| \  }}}d}n6t          |           dk    r| \  }}nt          |           dk    r
| d         }d}|dv r|dk    r|n|}|rt          |          z  t          v r"t          xx         t          |          z  cc<    d	d
t          |          i           dxx         dz  cc<   t                                          d                                  d S i }t          |t                    rct          |                                          d d         D ]9\  }}	t          |	          }
|
d d         t          |
          dk    rdndz   ||<   :|dv r8	                    |t          |t                    r|ni d           t          v r;t                   	                    |t          |t                    r|ni dd            d|pd|||d           t                                                      }|d<                |d<    d|           	 ddlm}m}m}  |          rK|5  t          |                    i                     }d d d            n# 1 swxY w Y   |r d|           n# t"          $ r Y nw xY wd S |dk    rt%                    D ]x}|                    d          r|r|                    d          |k    rEd|d<   |                    d          |d<   t'          |                    dd                    |d<    nyt          v rt%          t                             D ]x}|                    d          r|r|                    d          |k    rEd|d<   |                    d          |d<   t'          |                    dd                    |d<    nydxx         dz  cc<    d|||||                    d          t'          |                    dd                    d            t                                                      }|d<                |d<    d|           d S d S )!NrZ  rY  tool.startedr  r   r   )reasoning.available	_thinkingr  r  r   r<   r  r1   )Nr  )r   r  F)r   r  doner  )
event_typer   r  r  r   r   r  )has_pending_pending_lockr  ztool.completedr  r   Tdurationis_errortool_complete)r  r   r  r  r  r  )rn   r7   r   r    r  r   r   r   r  r   r   r  tools.approvalr  r  r  rA   r$   rv  r   )cb_argsr  r  r   r  r  reason_text	args_snapr   r  s2_tool_stats_has_pendingr  r  r|   r-  	shared_tc_checkpoint_activityr  _live_tool_callsr  r  r  r  r   r  s                     r&   on_toolz%_run_agent_streaming.<locals>.on_tool
  s   !
w<<1$$6=bqbk3Jgtt\\Q&&*1'D'4!/JJ\\Q&&'.$J\\Q&&"1:D!/J!EEE-7;P-P-P''VZK" )'3{+;+;;$(===1)<<<K@P@PP<<<K&#k2B2B)CDDD21555:55500<VWX<YZZZ&(((F	dD)) S $TZZ\\ 2 22A2 6 S S1 VV')$3$xCGGcMM55r'R	!!777$++ $(24(>(> FB- -   
 !$:::.y9@@$(,6tT,B,B$JDD$)B B   
 C&0&BN $#* )	! !    #(''"3"3"5"5K0:K-+?+?+A+AK(C
K000__________'<
33 3!& G G$(j")E)E$F$FG G G G G G G G G G G G G G G  3 #J 2 2 2&   F!111#+,<#=#= " "";;v.. %$# "w{{6':':d'B'B.2GFO2;--
2K2KGJ/26y}}ZQV7W7W2X2XGJ/!E	 (C !$:::)12H2S)T)T & &I(}}V44 ) (#' &9==+@+@D+H+H48	& 18Aj8Q8Q	* 58<Y]]:W\=]=]8^8^	* 5 %	 ,I )+++q0+++C&0 $#* )$-MM*$=$=$(z5)I)I$J$J* *    #(''"3"3"5"5K0:K-+?+?+A+AK(C
K000FE 21s6   /K $J6*K 6J::K =J:>K 
KKc                     	  | ||           t                                                      }|d<                |d<    d|           d S # t          $ r  t                              dd           Y d S w xY w)Nr   r   r  z3Failed to update live prompt estimate on tool startTr  r    r  rC   r  r  )r   r   r  r  r  r  r  r   s       r&   on_tool_startz+_run_agent_streaming.<locals>.on_tool_startq
  s    g++L$EEE"'''"3"3"5"5K0:K-+?+?+A+AK(C
K00000  g g gLL!VaeLffffffg   AA &A:9A:c                     	  | ||           t                                                      }|d<                |d<    d|           d S # t          $ r  t                              dd           Y d S w xY w)Nr   r   r  z8Failed to update live prompt estimate on tool completionTr  r  )	r   r   r  r  r  r  r  r  r   s	        r&   on_tool_completez._run_agent_streaming.<locals>.on_tool_complete{
  s    l..|T?SSS"'''"3"3"5"5K0:K-+?+?+A+AK(C
K00000  l l lLL![fjLkkkkkklr  )	SessionDBuO   [webui] WARNING: SessionDB init failed — session_search will be unavailable: )r3  )rX  r\  r^  api_keyr   r  z2[webui] WARNING: resolve_runtime_provider failed: zcustom:)r   )_resolve_cli_toolsets)Sessionr   rH  enabled_toolsetsz9[webui] WARNING: failed to read per-session toolsets for : r   fallback_providersr   key_env)r   r   r  r	  r  ry   	max_turnsr  )parse_reasoning_effortreasoning_effortwebuic                 "     | |          S r   r   )r  r  r  r  r  r   s     r&   <lambda>z&_run_agent_streaming.<locals>.<lambda>1  s     .D.D ':|S/ / r;   )r   r   r  r	  platform
quiet_moder  r   r   
session_dbstream_delta_callbackreasoning_callbacktool_progress_callbackclarify_callbackr  interim_assistant_callbacktool_start_callbacktool_complete_callbackstatus_callbackmax_iterationsr  acp_commandcommandacp_argsr  credential_poolgateway_session_keyz.[webui] Created ephemeral agent for session %s)rY  rZ  r  )r  z+[webui] Reusing cached agent for session %sr  r  r  r  _session_db_api_call_count_interrupted_interrupt_message)SESSION_AGENT_CACHE_MAX)lastz([webui] Evicted LRU agent from cache: %sz([webui] Created new agent for session %sz&Failed to interrupt agent before startCancelled by userz&Failed to unregister approval callbackz%Failed to unregister clarify callbackz#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.personalitypersonalitiessystem_promptr  tonezTone: stylezStyle: r   c              3      K   | ]}||V  	d S r   r   rz   s     r&   r   z'_run_agent_streaming.<locals>.<genexpr>  s'      7O7OaQ7O7O7O7O7O7O7Or;   r9  rs  compression_countc                  L   d}                      d          s	 d         }|| k    r25                      d           d d d            n# 1 swxY w Y   |} n2# t          $ r%}t                              d|           Y d }~nd }~ww xY w                     d          d S d S )Nr   r  T)
skip_indexz#Periodic checkpoint save failed: %s)r  r~  rC   r  r  )last_saved_activitycurr  _agent_lockr  _checkpoint_stoprE  s      r&   _periodic_checkpointz2_run_agent_streaming.<locals>._periodic_checkpoint  s*   &'#*//33 OO215!444!, 8 8 !$ 7 7 78 8 8 8 8 8 8 8 8 8 8 8 8 8 825/$ O O O%JANNNNNNNNO +//33 O O O O Os:   A AA AA AA 
B
%BB
)rz  r6  zckpt-   )r  r  r   r  )user_messagesystem_messageconversation_historytask_idpersist_user_messagerp  r   rm  r   r  )r   rp  )r  r  )r  r   ri  answer)
missing_okzMSkipping stale stream writeback for session %s stream %s; active_stream_id=%sr   r   c              3      K   | ]S}|                     d           dk    o5t          |                     d          pd                                          V  TdS r   rm  r   r1   NrA   r7   rm   r  s     r&   r   z'_run_agent_streaming.<locals>.<genexpr>i  so       ' ' EE&MM[0XSy9I9I9OR5P5P5V5V5X5X' ' ' ' ' 'r;   _last_errorr_   rH   rW   rU   r[   rV   rX   z;[webui] self-heal: retrying stream after credential refreshc              3      K   | ]S}|                     d           dk    o5t          |                     d          pd                                          V  TdS rE  rF  r  s     r&   r   z'_run_agent_streaming.<locals>.<genexpr>  sp       /" /"() %&EE&MM[$@$hSyIYIYI_]_E`E`EfEfEhEh/" /" /" /" /" /"r;   z([webui] self-heal: retry also failed: %srZ   r\   .apperrorz**z:** z

**)r   r   r   r  rl   provider_detailsz?Stamped profile=%r on continuation session %s after compressionz0Failed to rename session file during compression)auto_compressionr  
compressedz4Context auto-compressed to continue the conversationr   r  rq  rr  ro  r  r  r  )r#  c                 J    g | ] }t          |          t          |          !S r   )r   r   s     r&   r}   z(_run_agent_streaming.<locals>.<listcomp>  s0    *k*k*k1WghiWjWj*k+;A+>+>*k*k*kr;   rl  z

[Attached files:r[  r2  r  g        r   gateway_routing_historyirY  _turnDuration_turnTps_gatewayRoutingr  r  rt  )get_model_context_lengthcustom_providers)config_context_lengthr   rU  c              3      K   | ]J}t          j        |         t                    r(j        |                             d           dk    F|V  KdS r   rm  Nr   rp  r   rA   r{   r  rE  s     r&   r   z'_run_agent_streaming.<locals>.<genexpr>  sl       n n&qz#==nBC*S/BUBUV\B]B]alBlBl BlBlBlBln nr;   assistant_started)r5  rq  assistant_message_indexz5Failed to append assistant_started turn journal event	completedc              3      K   | ]J}t          j        |         t                    r(j        |                             d           dk    F|V  KdS rX  rY  rZ  s     r&   r   z'_run_agent_streaming.<locals>.<genexpr>/  sm       %z %zS(21:c?D(I(I%zNOjY\oNaNabhNiNimxNxNx &)NxNxNxNx%z %zr;   z-Failed to append completed turn journal eventr}  sync_to_insights)sync_session_usage)r   r  r  r  r   r  message_countz"Failed to sync session to insights)r  r  r  duration_secondstpsgateway_routing_drain_pending_steerpending_steer_leftover)r   r   z,Failed to drain pending steer for session %s)evaluate_goal_after_turnhas_active_goal)r   goal
evaluatingu   Evaluating goal progress…goal_evaluating_progress)r   staterh   message_key)user_initiatedr   should_continue
continuingidlerm  goal_continuingmessage_args)r   rl  rh   rm  rs  decisioncontinuation_promptgoal_continue)r   ru  r   rh   rm  rs  rt  z0Goal continuation hook failed for session %s: %s)rp  r   )r  r   r  r  r  r  rn  z[webui] stream error:
z<[^>]+>r;  r>  rY   rR   zI[webui] self-heal (except path): retrying stream after credential refresh_agent_kwargszWSkipping stale stream self-heal writeback for session %s stream %s; active_stream_id=%sz0[webui] self-heal (except path): retry succeededz1[webui] self-heal (except path): retry failed: %s)zAuthentication errorr[   zThe selected model may not be supported by your configured provider. Run `hermes model` in your terminal to switch providers, then restart the WebUI.)r^   r_   r1   zSSkipping stale stream error writeback for session %s stream %s; active_stream_id=%sinterrupted)r5  rq  r   z/Failed to append interrupted turn journal eventr   )r   rA   r   r$  r7   r   r!   rC   r  r  r  Eventr   r   r
   r   r   r  rB   r    begin_sessionr  r  r   r   r   r%  r&  r   r   rm   r8   r   rj  r   rM  r   rU  r   r  r	   r   r   api.profilesr  r  r  r$   r   r   r  r   r   r'   	_ENV_LOCKr   tools.mcp_toolr  r  r  r  r  r  r-   r   hermes_stater  printr   r   r`  rX  ra  r]  r   r  r   r  r   r
  rL  r  r   existsload_metadata_onlyr   r   inspect	signature__init__
parametersr  hashlibr  rY  rZ  r  sha256r2  	hexdigestsortedmove_to_endr  r  hasattrr  r  r   r  r  r  r'  closer(  r)  r*  r+  rn   popitemtuple	interruptr  rb  r   ephemeral_system_promptrp  r  r  r~  r9  run_conversationr  rv  pathlibr   unlinkr  r  r  r  r  rO  r   rg   rh  rb  rt   rB  r  r8  r;  r9  r   rN  r   r   r   r   renamer
  r   r  compression_anchor_visible_idxr  compression_anchor_message_keyr  r  compression_anchor_summaryr  r   r  rR  rt  r  r  r  r.  r   r  r   roundr   rd  rP  r  r  rt  r~  rT  r  r  nextr  r~  api.state_syncr`  	api.goalsrg  rh  r   r  compactr   r  r  r  r  	traceback
format_excr?  r@  dirrO  rP  )r   r   r   r   r  r2  ri  rj  rk  _rtold_cwdold_exec_askold_session_keyold_hermes_homeold_profile_envr  _metering_threadr  _ckpt_threadprovider_contextr  r  r  _profile_home_path_profile_home_profile_runtime_env_resolved_profile_namer  _thread_envr  _approval_registered_unreg_notify_reg_notifyr  _clarify_registered_unreg_clarify_notify_reg_clarify_notifyr  _self_healedr  r  r  r  r  r  _AIAgentr'  r  _db_errresolved_modelresolved_providerresolved_base_urlresolved_api_keyrX  r]  _e_cp_key_cp_base_get_config_cfgr
  	_toolsetsr  r   _session_path_session_meta	_override_ts_err	_fallback_fallback_resolved	_fb_entry_entry_inspect_agent_params_max_iterations_cfg_raw_max_iterations_agent_cfg_for_iterations_parsed_max_iterations_max_tokens_cfg_raw_max_tokens_agent_cfg_for_tokens_parsed_max_tokens_parse_reff_effort_cfg_effort_raw_reasoning_configrw  _hashlib_jsonrY  rZ  	_sig_blob
_agent_sig_cachedr+  evicted_sidevicted_entry_evicted_agent_key
_old_valuer  workspace_system_msg_personality_prompt_pname
_agent_cfg_personalities_pval_parts_pending_started_at_turn_started_at_previous_messages_previous_context_messages_pre_compression_countr;  r=  r   _answer_mr  _result_messages_next_context_messages_raw_content_cleaned_part_assistant_added	_last_err_err_str_classificationrc   rd   
_err_label	_err_type	_err_hint_heal_result_heal_rt_SAC_SAC_L_heal_ok
_retry_exc_error_payload_error_message
_agent_sid_compressedold_sidnew_sidold_pathnew_path_cached_entry_compressorvisible_after_now_looks_default_looks_provisional_invalid_existing_title_should_bg_title_u0_a0r  r  r  r   display_attachmentsrs  r   	base_text_rm_turn_duration_seconds	_turn_tps_gateway_routing_history_dm_cc_for_saverT  _cfg_ctx_len_cfg_custom_providers_model_cfg_for_ctx_raw_cfg_ctx_parsed_cfg_ctx_raw_cp_resolved_cl
_legacy_cl_latest_assistant_idx_latest_assistant_load_settingsr`  r   rw  _get_cl_fb_cl	_sess_lptre  	_leftoverrg  rh  _goal_decision_last_goal_response	_goal_msg_goal_content_goal_parts
_goal_part
_goal_textrt  _goal_messageru  	_goal_excraw_sessionmeter_statsr  rJ   	_stripped
_exc_lower_exc_is_quota_exc_is_rate_limit_exc_is_auth_exc_is_not_found
_exc_label	_exc_type	_exc_hint_heal_kwargs_heal_agent_SAC2_SAC2_LrT  _retry_exc2r9  r  r  r:  r  r  r  ry  rz  r   r  r  r  r  r  r  r  r  r{  r  ry   r  r  r  rE  s   `   `                                                                                                                                                                                                                           @@@@@@@@@@@@@@@@@@@@@@@@@r&   _run_agent_streamingrD    s%e   " 	IAy9;;i..y//	 	 	 	  ^	^0*$)++FF   
  	^ 	^ 	^LLMX\L]]]]]	^A
CGLOOO ?$$L	 / /".Y)+I&+-i(,.y)	/ / / / / / / / / / / / / / / E$%3 !"%(UU"/ / / / / / / / / /./ / / / / / / /5 5 5 5 5 5 5 5p 
GG)$$$
 _&&N
# 
# 
# 
# 
# 
# 
# 
# !'/?MMM9 9 9 9 9 9     4 LKz-
##)9LLLL$y//4466>>@@AA ) %%''--///,d33 	
 ,3t-j99    	C9&>?@@@n6 '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-w6	,         
 "=!<WQ	SW=X=X!Y!Y 233M#:#:;M#N#N   	, 	, 	,JNN="==M#% '+$$$	, ")It!<!<% 	..@@@@@@)@)@)B)B&& . . .)-&&&. . 	
 
 	&&+&&& 	$%%%
  	B 	BXXCWXXXOjnn^44G:>>*;<<L jnn-ABBO jnn];;OJ2333),Q[)9)9BJ~&,/BJ()/9BJ+, 
B,9
=) ,7,,T--@-@AAA)	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	BJ	999999     	 	 	D	  %
	S       / / / / /K
$7888#'   	S 	S 	SLLQRRRRR	S $ $	R       
- - - - -  
,>???"& 	R 	R 	RLLPQQQQQ	R*	 *	 *	Xv	BK L O! $(>#3#3a#7"8'(c#*+&
' 
' 
' 
' 
' 
' 
' 
'! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !	 	 	 	 	 %&3      $	 	 	 	 	j j j j j j j j j j j j jXg g g g g g g gl l l l l l l l %H!">"@"@AAA K222222'ikk   qhoqqy}~~~~~~~~~CY+E3CDDD D@N-/@  $]VVVVVVPPPPPPFF,/   $'779#5#5 ( <(+
(;(;%( <(+
(;(;% ] ] ]O2OOW[\\\\\\\\\] +S11 16G6R6RS\6]6] 1$FGX$Y$Y!' /G /'.$( 1X 1(0% =<<<<<;==D 988888--d33Iw;;;;;;;; +.B.B.B B '')) 
.$+$>$>z$J$JM Ub k7I4 P P PgkI  .$-	 w w wiR\ii`giiquvvvvvvvvvw !122\dhh?S6T6T\X\I!%  !	i.. *"+ " "%fd33 "

78K8K "(.I!E	400 *Y]]75K5K * )I !*w!;!;$-MM*b$A$A$-MM*$=$=#,==#;#;#,==#;#;* *& '&&& 2 283D E E PQQM #'+&*#EOPTVZE[E[,cDHHWb,A,A,Aac)7>> U*C*G*G*T*T'&.:dD3I3I. +/((;*?*?'&2-01D-E-E*-11.D+ + + +&*###+ #O'"&((<"8"8"*,0HHWb,A,A)!"7>> R*?*C*CL*Q*Q".),_)=)=&)A--*< ' ' '"&')LLLLLL7A$7M7MUdhhw333SUEOP[]aEbEblkoo.@AAAhl$/K$<$<!! ) ) )$(!!!) !$**( !!*1%&&.#/'.      #  M0 "]227H7T4E01+}<<>R:;$557D34'=88:J67 M113I/0=005H5T2E./},,1L.=l+]**,/GGJ,?,?j)--/2wwy/A/Am,]**,/GGFOOj) M113677;L3M3M/0
 %557A34
  \Y 11=11MzZZZZ****$$$$TTTTTTTT!KK"(bOO%5%;$C$C$E$EFFPPRRSVTVSVW%+%+'-2#)r&,")2:F9%%%%+ "'R!)" "# ( # #	$ &__Y-=-=-?-?@@JJLLSbSQ
- ` `155jAAG `71:#;#; '
+77
CCC%RT^___` ` ` ` ` ` ` ` ` ` ` ` ` ` ` $ 3@2C2CD[2\2\E/3@3D3DE]3^3^E0u&;<< ]4A4E4EF[4\4\1u&>?? c7D7H7HIa7b7b4u&788 U0=0A0ABS0T0T-u&BCC k;H;L;LMi;j;j8u&:;; [3@3D3DEY3Z3Z0u&899 W1>1B1BCU1V1V.".
 #5-88 %U=N=Z% % 1 7 7 9 9 9 9#, % % % $%,7)u&788 201- un55 3-2*u&:;; 8370$H55}55E1 b b;@*:M+J7+77
CCCFFFFFF!"5669PPP9L9T9TZ_9T9`9`6K%EOP]_dEeEe1oq1A1Ako#1#='.ZgimBnBnBz$2$>$D$D$F$F$F#, % % % $%"LL)SU`aaa ""5669PPP	b b b b b b b b b b b b b b b& LL!KZXXX  
 
-2	*,,i1H1O1O1Q1Q,O(@AAAA$ O O O%MNNNNNOC9.A"BCCC
 
 
 
 
 
P     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B Bz '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-y 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 6c!+6F6FGGMPak P P P ! #'Qt44F 9!XXgr22
!+!D!Dnd33 
9.8P8P*62E!%.. 9"'))OR"@"@"[EIIhXZD[D[!\ 99V,, D"MM*B5=*B*BCCC 99W-- F"MM*DE'N*D*DEEE.2ii7O7O67O7O7O.O.O++.1%jj+" D0C-")!-A4"H"H
 7JZ22ty{{!%aj&6B!7!7)U)!,,* *& &-3T::#Q& &"(
O 
O 
O 
O 
O 
O 
O 
O  )00  @ @???@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ %++D-Z^--  L    ;M8U`bkquvvvL++)3%?@Z%[%["%- ,  F  "6::j#9#9#?R@@  B!"d++ v+0M0M"%bffY&;&;"<"<F.8fjjQ[]_F`F`aa./!DD!%%	     $/$((***"NNNLL((//4/@@@@    DL     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B Bz '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s  + $$&&&'!!"!--- we we  )Ea)S)S KKg<<<!#5t<<	   we we we we we weB     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B Bz '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-Y $*::j#9#9#W=W )D.$* *& &<"G&./0BDTUU	 
 * 
Y 
YB!"d++ 	Yv+0M0M')vvi'8'8%lC88 Y'<\'J'JH'<77089'd;; Y)5 Y Y#-eT#:#: !Yz%))TZJ[J[]`?a?a !Y4I%PV-4X4XE&M $' ' '$jj44:' ' ' $ $ 
 ( ` ` '}d C C `vzzRYGZGZ `^`I1:Bs9~~~H&> !+/>>'9' ' 'O
 !0 7;L LI.v6/IH  n<%4W%=
$3F$;	$3F$;		! j<, j< (,#@-3Z$ $ $/"KK(efff"*C/7||I/F/F,#4 M4<LL4L4L 1#4 M4<LL4L4L 1)*;SAA AFWFbFbclFmFm A4VWh4i4i 1'7 !?G !?7>$4'8 !AX !A8@$57GM)48IM*55CM'28IM*50MAACK<<PaCbCb.? @$,H$=$=}$=$=E!- C C=B	 :C C C C C C C C C C C C C C Crrrrrrrr!' = =49:3FZ 0 $ 0 0 < < <= = = = = = = = = = = = = = = ,0L*/K1/4/E/E1=3G9STn9o9o,69A 0F 0" 0" ,/ /" /".:.>.>z.J.J.Pb/" /" /" ," ," ,1 &1 !) $- 1 1 1 &$NPZ!" !" !" ,1	1
  ( 8L,D)5 4:::j3I3I3gMg 09T$>$4:" :" 6 6L 2-W$6$>$?@RTd$e$e$,	." ."
 48 0/ )@J(7I!N &
 " <%<
$3	J "	 &5W%=
$3F$;	$3F$;	 ( % )@$8:(8(8(8%%* *
 J777 DAFFF-1*15.02-/3,$/'zJ'z'zN<N<Ny<Y<Y<g]g'z'znw'z'z'z),TY[[)9)9&*	* * *--i88 [AOPYAZN+=>
)).999!FFHHHH( ! ! ! D!
 _we we we we we weB     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B Bz '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-m %UL$??
# ,'*
":":(G(G*->->->>H*->->->>H#*AL 9 )? $:	]2G    F F"h..08W0E0EHW-F F F F F F F F F F F F F F F 2 ? ?7B+G4+/>>>? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
 YXXXXXXX1 I I(;(?(?(N(N( I;H/8I I I I I I I I I I I I I I I  (( ]1B1B ]]$OOH5555& ] ] ]"LL)[\\\\\]"&K" +")%1Et"L"LK" +w{<OQR'S'SVl'l'l&* $?
]a$b$b$bM:GQAs=11A5666T 4 O\e7b8IJJJae 4 4I:1:FF R=a>PQQ4 4A0 C!#Y'   
 y{{* 4 4B!"d++ 4BFF;4G4G 4PRPVPVW\P]P] 4*-d));7j((AGz,A,A,A(QW==AG"#'Z"7"_17j;P"_XYX_T_%:17AJ%O%O"*H*Q*Q'#T'9T=T b$Q(=uEEE`I` ! # D7
CCHC  'u.EqIINQ '/JA N N SRS!(0Ld!S!S!##%1AN 1$$&3AO!-'5A$ ?J$4  
  *%)")-&(*%'+$  	&*k*k*k*k*k'%aj11 & &55==F22&)!%%	2*>*>&?&?G]sw]]7M(N(Nq(Q(W(W(Y(Y(Y  FNI("~88GCRCLH<T<T3F- 0 %
 # "qz "'
33 " "%c400 "SWWV__5S5S/>C,!E1-0dikkEJZD[D[6[-\-\**  1 1 1-0***1 	  X%;a%?%? %eM&:&:=S&SUV W WI#D$2$;e'8	$ $ $  $ ?(8A%#GA/H$$O$O$USUVVHOO$455508A-: "'
33 " "%c400 "SWWV__5S5S389OQR3S3SC0(42;J/ J9I$5 6!E  'u.BDII _'.|=Mq'Q'Q'VUVA$)0?QST)U)U)ZYZA&+2<AUWX+Y+Y+^]^A(  q"2A66 21QQQQQQ'+04-!JTUY[_J`J`1h'21F1F1Ffh.)*<dCC 
-/A/E/EFV/W/W#/#;%-:=l:K:K+:Q+>+>;JL,5z+B %- %- %- )-%- GQQUW[F\F\&fdhh/A&B&B&BbfG)'488 @8? 5( ! ! ! D!'?'?#E7N4HbIIOR#E:r::@b2>%6%<"-B( ( ( ( </;A,$ ! ! !
	!cccccc+5: 'w8L" M M SQS 'z2 > > D", ,L  , @3? 0( ! ! ! D!$     ! qQZ q,0n n n nc!*oo.A2r(J(J n n n- -)
 -8,-J7L,M)q@ ! )-@278I8M8Mk8Z8Z8i^b^g^i^i2j2j?T!" !"     ) q q q"LL)`koLpppppq  ee<L%)4.2ikk;?%z %z %z %zE#aj//A:MrSU4V4V %z %z %z$(<" <"     % e e e%T_cdddddemwe we we we we we we we we we we we we we werCFFFFFF!>##''(:;; 
AAAAAA&&#$<%&^%8q&'o&:'('7#g&)!*oo     C C CABBBBBC !-!."0$)*@!$D$D	 E $(e <+;'( %!5t<<C Y*1#7G*K*K*Pq&',3C9KQ,O,O,TST().5c;OQR.S.S.XWX*+ 99-.. &%XXXXXX#'L,0)FPQUW[F\F\-dTXXgr-B-B-Bbd*%&8$?? )+=+A+ABR+S+SL+7!)69,6G6GO'6':':7F(1:'> !) !) !)$(D!)BLTSWBXBX"b$((+=">">">^b%gt44 <4;1$   !(#E7N4HbIIOR#E:r::@b2>%6%<"-B" " " %   !(#E7N4HbIIOR#E:r::@b" "  928./    D
 99122 <#A';Q??D1	 <2;E./	Y'.u6Ld'S'S$6JT00222PT	 C0&0 #I3 3     Y Y YKZXXXXXY=hOOOOOOOO# ??:Ta+b+b+b %'NN*,'%-aj.>B%?%?  	))T:: %immF>S>SWb>b>b$(1i(D(D%mT:: 	K*,K.; L L
#-j$#?#? !L1;1G1G1d:>>ZcKdKdJ'1 %L(3(:(:3z??(K(K(K26))K2H2H//25m6Ir2J2J/C&0!-#@'A	! !    &>%="+'+%2	& & &N */R #HLL$;$;$Ar B B H H J J  C&019>O1P1P!\V\#0'/||M'B'B'r\iGqGXGXoq(0^(D(D(J$,! !    << 122 *-hll;P.Q.Q.WUW*X*X*^*^*`*`'*  25jAAAO*43F$7'4+3<<+F+F+[J[,4LL,H,H,NB(0. .     h h hOQ[]fggggggggh))++QZz(Z(ZZKC$7$D$DuUUVVV''++--K(2K%""?E:::"";666C
K((( =C =C = 7,S#agm2D2D2J2J2L2LcSXY   %''''
 L<"<=== .ae<<<     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B B     $ K(AK!M*----  K K KLL!IJJJJJK" J'<'HJ))*5555  J J JLL!HIIIIIJ B B(7(=(=(?(? 8 8$D*!)2:>>$+E+E+E+E-7"*T**?BJNN>4$H$H$H$H3:bj0'8I4)P)P)P)P6Bbj!23"*BJNN;OQU,V,V,V,V9Hbj!56"*BJNN=$,O,O,O,O2Abj/B B B B B B B B B B B B B B B B  k( k( k(')*>*@*@@MMMMa&& F:sG44	F63	2288::	G]]__
27A>>'/3DD .f5E^P]L]&v./A+F37HH  c	D(/&*A?SYCZ $-	JJ   _	D(/&*A?SYCZ $-	JJ  [	D Mi8%+Z  'KK klll#'L"C'/||I'>'>$, E,4LL,D,D), E,4LL,D,D)!"3S99 9>O>Z>Z[d>e>e 9,NO`,a,a)/ 7G 7/6,0 9X 908-:ISUU:R:R4#6#6#6XZL.>L+/@L,,:L)/@L,(M99:B,,GX:Y:Y%67"*(":":\":":K% A A5@	2A A A A A A A A A A A A A A Allllllll  6 6-8*,Ej)))*5556 6 6 6 6 6 6 6 6 6 6 6 6 6 6 #(K'i'2'C'C)5+?1KLf1g1g$.19 (D ( ( =/; 0 4 4 6 6 6+7 , 1 1" 1 = = =7B7NT^TjTlTlI!* ) )'0 !+9UVWYb9c9c !+$*KK )B(/<(L(L(1(/3Et(L(L	%& %& %& %+) ) ) ) ) ) ) ) ) )| '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 4@3C3CJ3O3O3mSm 09T$>@P:" :" 6 6L 2-W$6$>$?@RTd$e$e$,	." ."
 !")) ) ) ) ) ) ) ) ) ) ) ) ) ) )* $VWWWP '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-c % i i i'Z\ghhhhhhhhi0,J	99
  	D(/&*A?SYCZ $-	JJ 0D,J	90)YOO=+ $$&&&'!!"!--- (3'>JDZD\D\I 'g 'g  )Ea)S)S KKm<<<!#5t<<	   'g 'g 'g 'g 'g 'g 'g 'g 'g 'gZ '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-] <A>>>%)")-&(*%'+$'^J^^N4F4Fy4Q4Q4\U\^^  {D  cLbvjsbvbvbvbv  JL   M!$TY[[!1!1"	" " "%%i00 S9G	9RN#56
!!.111FFHHHH    D  gg<L%)6.2ikk*3     % g g g%VaefffffgM'g 'g 'g 'g 'g 'g 'g 'g 'g 'g 'g 'g 'g 'g 'gP 	J''''''''Wk(` '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- '  """#b)))MA1488IEEA5t<< Fi|<<<<'9kBBB 	- 	-K	4(((Y---	4000#It444!%i666"&y$777#It444!),,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s  9%B &CC3)D((D,/D,(C.Cs $B#PPP">Q!  Cs !.RCs RCs )R: 9Cs :S	Cs S		A	Cs DX0$Cs 0X44Cs 7X48Cs <Y Cs 
YCs YCs "Y> =Cs >$Z%"Cs $Z%%Cs -[	 Cs 	$[0-Cs /[00Cs 7BCl ^% $Cl %
_/_Cl _&Cl 4Aa Cl 
a9a4/Cl 4a99A,Cl &Ad9 8Cl 9
e$eCl e$$ECl ,Bm 
Cl mCl mCl  A0o Cl o Cl o  Cl $A*q Cl qCl qG$Cl Az*Cl *z..Cl 1z.2ECl @A@ @Cl @
A@)@&Cl @(A@)@)ACl BAAE+CAAD!D AE+D!
AD.D+AE+D-AD.D.1AE+ECl E+AE/E/Cl E2AE/E3%Cl F5AT;GAG$G#AT;G$$AHHAT;H
AHHAT;HCl H(Cs IAI ICs I$AI4I1Cs I3AI4I4Cs I<AJ JCs J$AJ/J,Cs J.AJ/J/
Cs J9DAOOCs OAOOCs O!AOO"Cs Q2B#AT"T"AT&T)AT&T/Cl T;AT?T?Cl UAT?UH
Cl ]A]1]%Cl ]1A]5]5Cl ]8A]5]9D7Cl b12Ac$ c#Cl c$
Ac1c.Cl c0Ac1c1Cl c5Cs dAd dCs d$Aed>Cs e AeeCs e	Ae eCs e$Ae<e9Cs e;Ae<e<
Cs fDAj'jCs j'Aj+j+Cs j.Aj+j/Cs l?B#Ao/o/Ao3o6Ao3o<0Cl p,ACIq>Cl r	Cs r"Ar. r-Cs r.$AssCs sAssCs sAs) s(Cs s)$AttCs tAtt
Cs tDAx;x/Cs x;Ax?x?Cs yAx?yCs {B#A~~A~~
A~~LCIJBJ6J*CIJ6BJ:	J:CIJ=BJ:	J>CIKBK4K(CIK4BK8	K8CIK;BK8	K<CILABMMCIM
BNM(BN
NCIN
BNNECIS,BTT CIT
BTTCITBTTCITCl TCs T6BU UCs U$BU)U&Cs U(BU)U)Cs U1BU= U<Cs U=$BV$V!Cs V#BV$V$
Cs V.DB[[Cs [B[[Cs [B[[Cs ]'B#B``B``B``$A,CIb)Bcb9CIcBc		c	CIcBc		cCIc"Bdc:CIdBd
	d
CIdBd
	dCIdBed9CIeBe		e	CIeBe		e+CIe9BffCIf%Bf7f4CIf6Bf7f7N-CIu%3BvvCIvBv(v%CIv'Bv(v(E0CI|
CA|$AB3}>B~~B3~B~,~)B3~+B~,~,AB32CA3
C@ =CA?C@ @ ACAACIACB-A?CBBCB-B
CBBCB-BCBBCB-BCIB!	CB-B*CIB,CB-B-ACIDACEECIE&CFF CIFCFFCIFA+CH	HCIH	&CH2H/CIH1CH2H2CIH5Cl ICIICl ICII	Cl IA*CJ8 J7Cl J8$CKKCl KCKKBCl M2
CS M=ACQ OCO/ O.CQ O/CPPCQ PCPPACQ QCS Q
CQQCS QCQQCS Q6CR RCS R;CSSCS SCSS
CS SCl S
CS*S'Cl S)CS*S*2Cl T=CU UCl U%CVV Cl VCVVCl VI6C_> _=Cl _>
C`.`C`)`$Cl `)C`.`.D'Cl eCs e.Ce: e9Cs e:$Cf!fCs f Cf!f!Cs f)Cf5 f4Cs f5$CggCs gCgg
Cs g&DClk;Cs lCllCs lCllCs lCsl.Cl:l9Csl:$Cm!mCsm Cm!m!Csm)Cm5m4Csm5$CnnCsnCnn
Csn&DCsr;CssCssCssCssCssCs sDb" sD]s#H>D]|!C|8|,D]|8C|<	|<D]|?C|<	} D]}C}6}*D]}6C}:	}:D]}=C}:	}>D]~A3DN7ADHA
DNADb" C&B#DFFDFFDFF#A*DHHDNHDH	HDNH DH	H!DNH?Db" KB#DN N DNNDNN
DN=NDN8N3D]N8DN=N=B
D]QAD\4RD]R%Db" T6B#DW&W&DW*W-DW*W3B1D\4Z%DZ:Z9D\4Z:
D[[D\4[D[[D\4[-D[;[:D\4[;'D\%\"D\4\$D\%\%D\4\(D]\4D\8	\8D]\;D\8	\<D]]Db" ]D]]Db" _%B#DbbDbbDbb"BDg+d0B#DggDg+gDg#g#Dg+g&Dg#g'Dg+bodyc                 .   ddl m}m} ddlm} t          |pi                     dd          pd                                          }t          |pi                     dd          pd                                          }|s || d          S |s || d          S |j        5  |j	                            |          }d	d	d	           n# 1 swxY w Y   |s || d
dd	d          S |d         }t          |d          s || d
dd	d          S 	 t          |          }	n # t          $ r  || d
dd	d          cY S w xY wt          |	dd	          pd	}
|
s || d
dd	d          S |j        5  |
|j        v }d	d	d	           n# 1 swxY w Y   |s || d
dd	d          S 	 t!          |                    |                    }nC# t$          $ r6}t&                              d||            || d
d|
d          cY d	}~S d	}~ww xY w || |d	|
d          S )uD  Inject a /steer payload into the active agent for a session.

    Mirrors the CLI's `/steer <text>` command (cli.py:6140-6155):
      - Look up the cached AIAgent for the session (PR #1051's
        SESSION_AGENT_CACHE).
      - Verify a stream is currently active for this session.
      - Call agent.steer(text) — thread-safe, stashes text in
        _pending_steer for application at the next tool-result boundary.

    The agent's loop calls _apply_pending_steer_to_tool_results() at the
    end of every tool batch and appends the steer text to the last tool
    result's content with a marker, so the model sees the steer as part
    of the tool output on its next iteration. The user's stream is NOT
    interrupted.

    If no agent is cached, the agent is too old to support steer, or no
    stream is active, return {"accepted": False, "fallback": "<reason>"}
    so the frontend can fall back to interrupt or queue mode. The
    fallback path is the existing behaviour from PR #1062.

    Returns 200 with {"accepted": bool, "fallback": str|None,
    "stream_id": str|None}.
    r   )jbadconfigr   r1   r   zsession_id requiredztext requiredNFno_cached_agent)acceptedrw  r  steeragent_lacks_steersession_not_foundr  not_runningstream_deadz'agent.steer() raised for session=%s: %ssteer_error)api.helpersrG  rH  apirJ  r7   rA   rm   rZ  rY  r  r   r}  r   r   r   r   rM  rC   r  r  )r4  rE  rG  rH  r  r  r   cachedry   rE  r  stream_aliverL  ra   s                 r&   _handle_chat_steerrW    s   0 #"""""""""""""
tzr|R006B
7
7
=
=
?
?C
++1r2288::D 3s71222 -s7O,,,		& 3 3)--c223 3 3 3 3 3 3 3 3 3 3 3 3 3 3 /qu:K(,. . / / 	/1IE5'"" /qu:M(,. . / / 	// / / /qu:M(,. . / / 	/ 	/ 	// q"4d;;Ct /qu-(,. . / / 	/		 8 8'4<78 8 8 8 8 8 8 8 8 8 8 8 8 8 8 /qu-(,. . / / 	/;D))** ; ; ;>SIIIqu-(8: : ; ; 	; 	; 	; 	; 	; 	;;
 1W8$46 6 7 7 7sT   $CCCD! !D>=D>-
FF
F!"G 
H+G?9H?Hr  c                 Z   ddl m} t          }t          }t          }t
          }t          }| |vr6t          |d|          |ur#|j        }|j        }|j        }|j        }|j        }|5  | |vr	 ddd           dS |                    |           }|r|	                                 |                    |           }|r`	 |
                    d           ny# t          $ r<}	ddl}
 |
j        t                                        d|  d|	            Y d}	~	n8d}	~	ww xY wddl}
 |
j        t                                        d	|  d
           	 ddlm} |r!t          |dd          r ||j                   n*# t          $ r t&                              d           Y nw xY w|                    |           }|rE	 |                    dddif           n*# t          $ r t&                              d           Y nw xY w|                    | d           |                    | d           |                    | d           |rt          |dd          nd}|                    | d          }|s+t          |d|          }||ur|                    | d          }t-          j        | d          }|s5t          |dt,                    }|t,          ur|                    | d          }t/          j        | g           }|s5t          |dt.                    }|t.          ur|                    | g           }ddd           n# 1 swxY w Y   |rt1          |          5  	 t3          |          }t5          ||           s:t&                              d|| t          |dd                     	 ddd           dS 	 t          |dd          }t          |dd          }t9          |t:          t<          f          rt;          |          ng }t          |dd          pd}t9          |j        t:                    r|j        nd}|r|d}tA          |          D ]4}t9          |tB                    r|                    d          dk    r|} n5d}|S|                    d          }|                    d          pd}t9          |tD                    r||k    r||k    s||v rd}|s@d|tG          tI          j$                              d}|r||d <   |%                    |           n+# t          $ r t&                              d!|           Y nw xY wd|_&        d|_'        g |_(        d|_)        |r|*                                nd} d}!| rtddl+}"|",                    d"d| |"j-        |"j.        z  #          *                                }!|",                    d$d|!|"j-        |"j.        z  #          *                                }!t_          |o|*                                          }#t_          |          }$|!s|#s|$rld%|!dtG          tI          j$                              d&}%|#r|*                                |%d'<   |$rt;          |          |%d(<   |j        %                    |%           |j        %                    d%d)dtG          tI          j$                              d*           |0                                 n+# t          $ r t&                              d+|           Y nw xY wddd           n# 1 swxY w Y   dS ),u/  Signal an in-flight stream to cancel. Returns True if the stream existed.

    Eagerly releases the session lock (pops STREAMS/CANCEL_FLAGS/AGENT_INSTANCES
    and clears session.active_stream_id) so new /api/chat/start requests succeed
    immediately after cancel, even if the agent thread is still blocked.

    The worker thread's finally block uses .pop(key, None), so the double-pop is
    a safe no-op. Session cleanup runs outside STREAMS_LOCK to preserve lock
    ordering (streaming thread does LOCK → STREAMS_LOCK; inverting would deadlock).
    r   rI  r   NFr-  z%Failed to interrupt agent for stream r  zCancel requested for stream zM before agent ready - cancel_event flag set, will be checked on agent startup)r  r   z,Failed to clear clarify prompt during cancelr  rh   z#Failed to put cancel event to queuer1   r
   r   r   zMSkipping stale cancel writeback for session %s stream %s; active_stream_id=%sr  Tr8  r;  r9  r   rl  r   r   )r   r   r   r2  z7Failed to recover pending user message on cancel for %sz)<think(?:ing)?\b[^>]*>.*?</think(?:ing)?>r<  z<think(?:ing)?\b[^>]*>.*rm  )r   r   _partialr   r  _partial_tool_callsz*Task cancelled.*)r   r   r  r   z.Failed to clear session state on cancel for %s)1rT  rJ  r   r   r	   r
   r   r   rA   r  r  rC   logging	getLoggerr`   r  r  r  r   r  r  r  r   r   r   r   r  r  r   r   r  rp  rv  r   r7   rB   r$  r   r  r8  r;  r9  rm   r?  r@  rB  rA  r   r~  )&r  _live_configstreamscancel_flagsagent_instancespartial_textsstreams_lockflagry   r  r[  r  r  _cancel_session_id_cancel_partial_textlive_partials_cancel_reasoninglive_reasoning_cancel_tool_calls
live_tools_cs_pending_user_pending_atts_raw_pending_atts_pending_started_msgs_for_recovery
_last_userr  _already_persisted_last_content_last_ts
_user_turnpartial_textr6  _re_has_reasoning
_has_tools_partial_msgs&                                         r&   cancel_streamr{  ;  s	    +***** GL%O'MLGL)W$M$MU\$\$\&#0&6$8#0	 RC RCG##RC RC RC RC RC RC RC RC
 	** 	HHJJJ  ##I.. 	 34444   !!(++11LILLLL        NNNGh''--Ky K K K  	IKKKKKK 9d;; 9&&u'7888 	I 	I 	ILLGHHHHH	I KK	"" 	DDh4G(HIJJJJ D D DBCCCCCD 	It$$$D)))It,,, DIRWUL$???d,00B?? $ 	H#L2GWWMM11'4'8'8B'G'G$15iDD  	F$\3JLabbN%:::$2$6$6y"$E$E!37	2FF! 	C /GI_``J!777%/^^Ir%B%B"eRC RC RC RC RC RC RC RC RC RC RC RC RC RC RCr  Pc$%788 O	c O	cNc!"4553CCC  KKg*!%7>>	    O	c O	c O	c O	c O	c O	c O	c O	c8'$+C1G$N$NM(/5JD(Q(Q%?IJ[^bdi]j?k?k$sD):$;$;$;qsM'.s4H$'O'O'TST$9CCLRV9W9W)a]a&$ B);)G%)
"*+=">"> & &B)"d33 &v&8P8P-/
 %-2*%1,6NN9,E,EM'1~~k'B'B'GaH  *-== >(N^B^B^#0M#A#A]VcEcEc9=$61 B(.+8-0-=-=0 0J
  - J<I
= 9.55jAAA    LLQ*    
 (,$+/(*,')-& @T[399;;;Y[	 S$$$$ !$(T(*L.1j3>.I !( !K !KKP577 
 !$(C(*I.1j3>.I !( !K !KKP577  "&&7&U<M<S<S<U<U!V!V!"455
 6 6* 6 +#,$(%(%5%5	* *L & N4E4K4K4M4M[1! W" ?CCU>V>V%:;L''555 ##'2"!$TY[[!1!1	% %    



 c c cMOabbbbbc]O	c O	c O	c O	c O	c O	c O	c O	c O	c O	c O	c O	c O	c O	c O	cb 4s   &L:9AL:<CL:
D2DL:D3L:)E65L:6$FL:FL:8GL:$G96L:8G99D5L::L>L>\ A[)3E(T[)%U[)UF$[)(\ )%\\ \\  \$'\$)r<   r   )r1   )NN)r1   r1   r1   )r  )r  )r~   )__doc__r.  rO  r  r[  r,  r   queuer?  r  r$  r  r  r  r   typingr   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   rS  r   r   api.compression_anchorr   api.meteringr    api.turn_journalr!   Lockr|  r'   r+   r)   r$   r-   r7   r   r:   rB   rG   r   rg   rt   r   rL  r   r   api.workspacer   r  r+  r   r   r   r   r   r   r   r   r   	frozensetr   bytes__annotations__r  r  r9  rF  rO  rS  rR  rZ  compilerg  rh  r`  rb  rj  rt  rw  r{  r  r  r  r   r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  re  ri  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  _TOOL_RESULT_SNIPPET_MAXr  r  r  r.  r6  rB  rU  rh  rD  rW  r{  r   r;   r&   <module>r     s[                				  				                      		8	$	$                                                    : 9 9 9 9 9 9 9 > > > > > >       A A A A A A IN	  0!!!!!!!   GGG  $3 4    .
 
c 
C 
 
 
 
C;u C; C; C;c C; C;Y] C; C; C; C;L S C s D     .c . . . .^ / . . . . . . . , , , , , ,
 ZYY * # # # # ! ! !   
 
 
C C C CL   B  Z] mp uy    ""S " " " " $)[M22Y~..y+''y+''Y~&&9k]##
)_%
&
&4 4d54<3/0   $ c d    , 4  C        F uy 3> 3> 3>C 3>3 3>`c 3>mq 3> 3> 3> 3>l     ,% % % % % %PC C    $      <C < < < < "rz"QRR (bj)GHH E E E E E EGC GC G G G G BG   # $ 3     ,  ,  ,F, , ,8
 
 
S    	A 	A4 	A 	A 	A 	Ac 3 5d3i;P    27 7 7 7S 7RV 7 7 7 7
t 
 
 
 
      2 s  C Y\    N NS Nc NRU N_b N N N N     &# $    ,
c 
 
 
 
$s $ $ $ $ 27 ( ( ($ (5c? ( ( ( (D ;% ;%;%;% ;% 	;%
 ;% 8C=#;% ;% ;% ;%|k03 k0 k0PUV^_bVcehVhPi k0 k0 k0 k0\/C /QT /Y^_ghk_lnqsv_vYw / / / /3ty 3 3 33 3 3mq 3  D  EM  NQ  ER  TW  Y\  E\  ] 3 3 3 3@ S # s X[ or   }A    &M S M # M (SV- M  M  M  M `Fc Fd F F F F
P< P<S P<S P<RU P<jm P< P< P< P<f9b 9bc 9bc 9bSV 9bgj 9b 9b 9b 9bx  .+ + +\  83 3 3l" " "  ,  	 	 	
 
C$J 
s 
S4Z 
 
 
 
O O O$	 	 	  $  W W WY Y Yx    ,D  S      S     # #    E E E EP  "D " " " "J
 
 
>: : :F T- T- T- T- T- T-N?I7d I7t I7 I7 I7 I7XIS IT I I I I I Is   1B8 8CC