
    `gj1`                      d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
m
Z
 ddlmZ ddlmZmZmZ ddlmZ ddlmZ  ej*                  e      Zd	Zd
e dZd)dZd*dZd+dZd,dZd-dZd.dZ	 	 	 	 	 	 	 	 	 	 	 	 d/dZ  G d d      Z!d0dZ"d0dZ#d1dZ$dZ%d2dZ&dZ'd3dZ(d4dZ)d5dZ*d6dZ+dddd d!	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d7d"Z,ddd d#	 	 	 	 	 	 	 	 	 	 	 	 	 d8d$Z-d%d&	 	 	 	 	 d9d'Z.g d(Z/y):u  Context compression — extract the AIAgent methods that drive summarisation.

Three concerns live here:

* :func:`check_compression_model_feasibility` — startup probe of the
  configured auxiliary compression model.  Warns when the aux context
  window can't fit the main model's compression threshold; auto-lowers
  the session threshold when possible; hard-rejects auxes below
  ``MINIMUM_CONTEXT_LENGTH``.

* :func:`replay_compression_warning` — re-emit a stored warning through
  the gateway ``status_callback`` once it's wired up (the callback is
  set after :class:`AIAgent` construction).

* :func:`compress_context` — the actual compression call.  Runs the
  configured compressor, splits the SQLite session, rotates the
  session_id, notifies plugin context engines / memory providers, and
  returns the compressed message list and active system prompt.

* :func:`try_shrink_image_parts_in_messages` — image-too-large recovery
  helper that re-encodes ``data:image/...;base64,...`` parts at a smaller
  size so retries can fit under provider ceilings (Anthropic's 5 MB).

``run_agent`` keeps thin wrappers for each so existing call sites
(``self._compress_context(...)``) keep working.  Tests that exercise
these paths see no behavioural change.
    )annotationsN)datetime)Path)AnyOptionalTuple)sanitize_memory_context)estimate_request_tokens_roughzCompacting contextu   🗜️ u:    — summarizing earlier conversation so I can continue...c                    t        | dd      }|y	 t        | dd      r|j                  d      xs dnd}t        | dd      r|j                  d	      xs dnd}||fS # t        $ r Y yw xY w)
a  Return the built-in memory text that can affect a system prompt.

    ``MemoryStore`` freezes this text until ``load_from_disk()``.  Rendering
    the frozen blocks after that reload lets compression retain the exact
    cached system prompt when it already embeds the current memory (see
    :func:`_cached_prompt_reflects_builtin_memory`).  An unreadable snapshot
    returns ``None`` so callers take the conservative rebuild path.
    _memory_storeN) r   _memory_enabledFmemoryr   _user_profile_enableduser)getattrformat_for_system_prompt	Exception)agentstorer   r   s       Q/root/.hermes/venv/lib/python3.12/site-packages/agent/conversation_compression.py_builtin_memory_prompt_snapshotr   :   s     E?D1E} u/7 **84: 	 u5u= **628b 	 4<  s   AA 	A*)A*c                    t        |       }|y	 ddlm} t	        d|      D ]'  \  }}|j                         }|r||vs y||   |v s' y y# t        $ r Y yw xY w)u2  Whether the cached system prompt already embeds current built-in memory.

    The retention fast path must NOT compare the memory snapshot before vs
    after the disk reload: on fresh-agent surfaces (gateway, TUI) the cached
    prompt is restored from the session DB and can predate mid-session memory
    writes that the fresh ``MemoryStore`` already picked up at init — the
    snapshot is then identical on both sides of the reload while the prompt
    itself is stale, and retaining it would latch old memory for the life of
    the session (and re-persist it via ``update_system_prompt``).

    Instead, verify the CURRENT (post-reload) rendered blocks appear verbatim
    in the cached prompt, and that no leftover block header remains for a
    target whose entries have since been emptied or disabled.
    Fr   )MEMORY_BLOCK_HEADERS)r   r   T)r   tools.memory_toolr   r   zipstrip)r   cached_promptsnapshotr   targetblocks         r   &_cached_prompt_reflects_builtin_memoryr"   V   s     /u5H: /:  M)!&)]:    s   A 	AAc                    	 ddl m} t               }t        |       |u xr t	        j
                  |d|      |u S # t        $ r Y yw xY w)a  Whether the live in-memory SessionDB class structurally predates locks.

    In the supported hot-reload skew, this module is new while the already
    imported ``hermes_state.SessionDB`` class (and its live instances) is old.
    Only that exact class identity may fail open. Proxies, nominal lookalikes,
    non-callables, and descriptor failures must fail closed. Static lookup
    avoids invoking a present-but-broken descriptor.
    r   )	SessionDBtry_acquire_compression_lockF)hermes_stater$   objecttypeinspectgetattr_staticr   )lock_dbr$   missings      r   !_lock_api_is_absent_on_session_dbr-   {   sY    *(MY& &&97	
  s   7: 	AAc                    dddifdi ff}|D ]1  \  }}t        t        |       |d      }t        |      s(	  || fi | 3 y# t        $ r!}t        j                  d||       Y d}~Zd}~ww xY w)zFRefresh durable automatic-compression guards on a built-in compressor.'get_active_compression_failure_cooldownrefreshT!_load_fallback_compression_streakNz)compression guard refresh failed (%s): %s)r   r(   callabler   loggerdebug)
compressormethod_callsmethod_namekwargsmethodexcs         r   %_refresh_persisted_compression_guardsr;      s     
3Y4EF	,b1L  , XVj);=	X:((X  	XLLDkSVWW	Xs   	A	A,A''A,c                    t        t        |       dd      }t        |      sy || |      }t        |xr) |j	                  d      duxr |j	                  d      dk(        S )zDReturn whether another path already rotated this compression parent.get_sessionNFended_at
end_reasoncompression)r   r(   r2   boolget)
session_db
session_idgettersessions       r   #_session_was_rotated_by_compressionrG      sh    T*%}d;FFZ,G 	7KK
#4/	7KK%6     c           
         ddl }dt        j                          d |j                          dt	        |       ddt        j                         j                  dd  S )	a  Build a unique holder id for the lock: pid:tid:agent-instance:uuid.

    The pid+tid prefix lets ops tell crashed/abandoned holders apart from
    live ones (expiry-based recovery uses the timestamp, but ``holder``
    is what shows up in diagnostics + log lines). The agent instance id
    and a per-acquire uuid disambiguate two co-resident agents on the
    same thread (background_review forks run on a worker thread, but
    on machines where compression itself dispatches to a thread pool
    we want each acquire to be unique).
    r   Nzpid=z:tid=z:agent=xz:nonce=   )	threadingosgetpid	get_identiduuiduuid4hex)r   rL   s     r   _compression_lock_holderrT      sZ     
ryy{m
#	##%&
"U)A
$**,""2A&'	)rH   c               4   |||d}|r||d<   	 t        j                  |       j                  }t        d |j                         D              }|r|S |j                         D 	ci c]  \  }}	||v s||	 c}	}S # t        t        f$ r d|icY S w xY wc c}	}w )aI  Return only compression kwargs accepted by an engine callable.

    Context-engine plugins can outlive additions to the optional host contract.
    Inspecting the callable before invoking it keeps those older signatures
    compatible without catching an internal ``TypeError`` and executing a
    stateful compressor twice.
    )current_tokensfocus_topicforcememory_contextrV   c              3  h   K   | ]*  }|j                   t        j                  j                  u  , y wN)kindr)   	ParameterVAR_KEYWORD).0	parameters     r   	<genexpr>z0_supported_compression_kwargs.<locals>.<genexpr>   s-       	'++777s   02)r)   	signature
parameters	TypeError
ValueErroranyvaluesitems)
compress_fnrV   rW   rX   rY   
candidatesrc   accepts_kwargsnamevalues
             r   _supported_compression_kwargsrn      s      )"J
 '5
#$2&&{3>>
  #**, N +5+;+;+=TKD%ASD%KTT z" 2 !.11	2 Us   A; %B2B;BBc                  F    e Zd Z	 d	 	 	 	 	 	 	 	 	 	 	 ddZddZd	dZd	dZy)
_CompressionLockLeaseRefresherNc                   || _         || _        || _        || _        |t	        dt        d|dz              }t	        dt        |            | _        t	        dt        | j                  | j                  z              | _	        t        j                         | _        t        j                  | j                  dd      | _        y )	N      ?g      N@g       @g?   zcompression-lock-refreshT)r    rl   daemon)_db_session_id_holder_ttl_secondsmaxminfloat_refresh_interval_secondsint_max_consecutive_failuresrL   Event_stopThread_run_thread)selfdbrD   holderttl_secondsrefresh_interval_secondss         r   __init__z'_CompressionLockLeaseRefresher.__init__   s     %'#+'*3D+:K0L'M$),S%8P2Q)R& *-s4$$t'E'EEF*
& __&
 ''99+
rH   c                :    | j                   j                          | S r[   )r   startr   s    r   r   z$_CompressionLockLeaseRefresher.start	  s    rH   c                    | j                   j                          | j                  j                         r>t	        j
                         | j                  ur| j                  j                  d       y y y )Nrr   )timeout)r   setr   is_aliverL   current_threadjoinr   s    r   stopz#_CompressionLockLeaseRefresher.stop  sT    

 <<  "y'?'?'A'ULLc* (V"rH   c                   d}| j                   j                  | j                        s	 | j                  j	                  | j
                  | j                  | j                        }|rd}g|dz  }|| j                  k\  r"t        j                  d|| j
                         y | j                   j                  | j                        sy y # t        $ r"}t        j                  d|       d}Y d }~d }~ww xY w)Nr   r   z#compression lock refresh raised: %sFrs   zZcompression lock refresh failed %d times in a row; stopping lease refresher for session %s)r   waitr|   ru   refresh_compression_lockrv   rw   rx   r   r3   r4   r~   )r   consecutive_failures	refreshedr:   s       r   r   z#_CompressionLockLeaseRefresher._run  s      !**//$"@"@A" HH==$$LL $ 1 1 > 	 '($ A% #t'E'EE>($*:*:
 ) **//$"@"@A  "BCH!	"s   <C 	C3C..C3r[   )r   r   rD   strr   r   r   r{   r   zfloat | NonereturnNone)r   z '_CompressionLockLeaseRefresher'r   r   )__name__
__module____qualname__r   r   r   r    rH   r   rp   rp      sU     26

 
 	

 
 #/
 

<+rH   rp   c                   | j                   sy	 ddlm}m}m} ddlm}m} 	  |d      \  }}}}} |d| j                               \  }}	||	sB |d|      \  }
}}|
3|r1|
|}	}d|v r)|j                  d	      r|j                  dd
      d
   dd }||	s>|r|dk7  rd| d}nd}|| _        | j                  |       t        j                  d       yt!        t#        |dd            }t#        |dd      }t%        |      rt'        |t               sdnt!        |xs d      } ||	||t#        | dd      |r|dk7  r|nt#        | dd      | j(                        }|r"||k  rt+        d|	 d|dd|dd|dz   d	      | j,                  j.                  }||k  r|}|}|| j,                  _        | j,                  j0                  }|r||z  | j,                  _        |rt5        ||z  dz        nd}t#        | dd      xs d }t#        | dd      xs d}|r|dk7  r|nd}|s	 dd!lm}  ||      j:                  xs |}|r| d"| d	n|}|	 d"| d	}d#| d$|dd%| d&|dd'|dd(|dd)|d*}|| _        | j                  |       t        j                  d+|	|||       yy# t        $ r d}Y |w xY w# t        $ r	 |xs d}Y w xY w# t*        $ r  t        $ r }t        j=                  d,|       Y d}~yd}~ww xY w)-au  Warn at session start if the auxiliary compression model's context
    window is smaller than the main model's compression threshold.

    When the auxiliary model cannot fit the content that needs summarising,
    compression will either fail outright (the LLM call errors) or produce
    a severely truncated summary.

    Called during ``AIAgent.__init__`` so CLI users see the warning
    immediately (via ``_vprint``).  The gateway sets ``status_callback``
    *after* construction, so :func:`replay_compression_warning` re-sends
    the stored warning through the callback on the first
    ``run_conversation()`` call.
    Nr   )_resolve_task_provider_model/_try_configured_fallback_for_unavailable_clientget_text_auxiliary_client)MINIMUM_CONTEXT_LENGTHget_model_context_lengthr@   r   )main_runtime()rs   autou/   ⚠ Configured auxiliary compression provider 'u   ' is unavailable — context compression will drop middle turns without a summary. Check auxiliary.compression in config.yaml and reauthenticate that provider.u   ⚠ No auxiliary LLM provider configured — context compression will drop middle turns without a summary. Run `hermes setup` or set OPENROUTER_API_KEY.uL   No auxiliary LLM provider for compression — summaries will be unavailable.base_urlapi_key&_aux_compression_context_length_configprovider)r   r   config_context_lengthr   custom_providerszAuxiliary compression model z has a context window of ,z$ tokens, which is below the minimum zE required by Hermes Agent.  Choose a compression model with at least i  zK context (set auxiliary.compression.model in config.yaml), or set auxiliary.compression.context_length to override the detected value if it is wrong.d   2   model?)urlparsez (u   ⚠ Compression model z context is z tokens, but the main model z's compression threshold was z2 tokens. Auto-lowered this session's threshold to u    tokens so compression can run.
  To make this permanent, edit config.yaml — either:
  1. Use a larger compression model:
       auxiliary:
         compression:
           model: <model-with-z[+-context>
  2. Lower the compression threshold:
       compression:
         threshold: 0.02du   Auxiliary compression model %s has %d token context, below the main model's compression threshold of %d tokens — auto-lowered session threshold to %d to keep compression working.z4Compression feasibility check failed (non-fatal): %s)compression_enabledagent.auxiliary_clientr   r   r   agent.model_metadatar   r   r   _current_main_runtimeendswithrsplit_compression_warning_emit_statusr3   warningr   r   r2   
isinstance_custom_providersre   context_compressorthreshold_tokenscontext_lengththreshold_percentr}   urllib.parser   hostnamer4   )r   r   r   r   r   r   _aux_cfg_provider_client	aux_model	fb_clientfb_modelfb_labelmsgaux_base_url_raw_aux_keyaux_api_keyaux_context	thresholdold_thresholdnew_thresholdmain_ctxsafe_pct_main_model_main_provider_aux_provider_labelr   _main_label
_aux_labelr:   s                                 r   #check_compression_model_feasibilityr   9  s.    $$t
	
 	

	
	#,H,W)q!Q 6446
	 >,[!-)Ix $$-x	(?x'8'8'=(0Q(?(B3B(G%> %6&%@)* +44 D 
 *-E&s#NN1 76:r:; vy"5%l3J|UX<Yb`cdpdvtv`w.!")%1Y[_"` ,=ARV\A\'bijoq{}  cA"44

$ ;)??.yk :(O ,1!4 5D)T12 31	2	 	 ,,==	" &M'M8EE$$5 //>>H!H, ((: ?GsK(2c9:BH "%"5<K$UJ;ArN %):f)D "  
 'A5 .77G< ( " -r.!13  
 &;b)<(=Q?J(Lq/!=-< # $< # $1
 2?q0A B) *2#8   *-E&s#NN, 	E #a  	# "	#p ! A*6*@&'AH   	 
BC	
 	

sf   K J B"K EK J0 ;A!K J-)K ,J--K 0K?K KK K7K22K7c                    t        | dd      }|r!| j                  r	 | j                  d|       yyy# t        $ r Y yw xY w)u  Re-send the compression warning through ``status_callback``.

    During ``__init__`` the gateway's ``status_callback`` is not yet
    wired, so ``_emit_status`` only reaches ``_vprint`` (CLI).  This
    method is called once at the start of the first
    ``run_conversation()`` — by then the gateway has set the callback,
    so every platform (Telegram, Discord, Slack, etc.) receives the
    warning.
    r   N	lifecycle)r   status_callbackr   )r   r   s     r   replay_compression_warningr      sN     %/
6C
u$$	!!+s3 %s  		s   2 	>>c                F    t        t        | dd            rt        |      S y)a  Return the correct flush baseline after a compression boundary.

    Legacy compression rotates to a fresh child session. That child has not
    seen the compacted transcript through the normal same-turn flush path yet,
    so callers must clear ``conversation_history`` to ``None`` and let the next
    persistence call write the whole compacted list.

    In-place compaction is different: ``archive_and_compact()`` has already
    soft-archived the previous active rows and inserted ``messages`` as the new
    active live transcript under the same session id. If the same agent turn
    continues with ``conversation_history=None``, the identity-based flush path
    treats those already-persisted compacted dicts as new and appends them a
    second time, doubling the active context and retriggering compression.

    A shallow copy is intentional: it captures the current compacted dict
    identities as history while allowing later same-turn appends to remain new.
    _last_compaction_in_placeFN)rA   r   list)r   messagess     r   &conversation_history_after_compressionr     s#    $ GE6>?H~rH   )z-[System: Your previous response was truncatedz*[System: The previous response was cut offz [System: Your previous tool callz@[Your active task list was preserved across context compression]z[IMPORTANT: Background process c                    t        | t              r| j                  d      nd }t        |t              r|S t        |t              rdj                  d |D              S y)Ncontent
c              3     K   | ]E  }t        |t              r3t        |j                  d       xs |j                  d      xs d       G yw)textr   r   N)r   dictr   rB   )r_   parts     r   ra   z _message_text.<locals>.<genexpr>7  sC      
$%  =DHHY$7=2>
s   AAr   )r   r   rB   r   r   r   )messager   s     r   _message_textr   2  sW    (27D(Agkk)$tG'3'4 yy 

 
 	

 rH   )_todo_snapshot_synthetic_empty_recovery_synthetic_verification_stop_synthetic_pre_verify_syntheticc                    t         t              r j                  d      dk7  ryt         fdt        D              ryt               j                         }|sy|j                  t              ryddl	m
} |j                  |       S )a  Distinguish human intent from user-role runtime scaffolding.

    A compaction summary pinned to ``role="user"`` (the compressor flips the
    summary role to preserve alternation when the tail starts with an
    assistant message) is scaffolding too: treating it as human intent would
    short-circuit anchor restoration with a message the model is explicitly
    told NOT to act on.
    roler   Fc              3  @   K   | ]  }j                  |        y wr[   )rB   )r_   flagr   s     r   ra   z(_is_real_user_message.<locals>.<genexpr>R  s     
?7;;t
?s   r   ContextCompressor)r   r   rB   rf   _SYNTHETIC_USER_FLAGSr   r   
startswith_SYNTHETIC_USER_PREFIXESagent.context_compressorr   _is_context_summary_content)r   r   r   s   `  r   _is_real_user_messager  G  st     gt$F(;v(E

?)>
??!'')D/0: <<TBBBrH   c                   |j                  d      }| j                  d      }t        |t              st        |t              ret        |t              rt        |      ndt        |xs d      dg}t        |t              rt        |      ndt        |xs d      dg}||z   | d<   n"|xs d d|xs d j	                         }|| d<   t
        D ]  }| j                  |d        y)af  Fold the human anchor into an existing user-role scaffolding turn.

    Used only when every insertion slot would create two consecutive
    user-role messages. The anchor text leads (it is the active task), the
    scaffolding content is preserved after it, and the synthetic flags are
    cleared because the merged turn now carries real human intent.
    r   r   r   )r(   r   z

N)rB   r   r   r   r   r   pop)r    anchoranchor_contenttarget_contentanchor_partstarget_partsmergedr   s           r   _merge_anchor_into_user_messager  ^  s     ZZ	*NZZ	*N.$':nd+K .$/  !3~/C+DEF 	 .$/  !3~/C+DEF 	
 )<7y"(b)n.B-CDJJL"y% 

4rH   c                r   d	d}t        |       D ]?  \  }} ||      dk7  r|dkD  r || |dz
           nd}|dk7  s-| j                  ||        y | r || d         dk7  r| j                  |       yddlm} |j                  t        | d               r| j                  |       yt        | d   |       y)
z?Insert the latest human turn without breaking role alternation.c                H    t        | t              r| j                  d      S d S )Nr   )r   r   rB   )r   s    r   _rolez'_insert_real_user_anchor.<locals>._role~  s    ",S$"7swwvATArH   	assistantr   rs   Nr   r   r   )r   r   r   Optional[str])	enumerateinsertappendr  r   r  r   r  )r   r  r  indexr   previous_roler   s          r   _insert_real_user_anchorr  {  s    B $H- w>[(6;aihuqy12TF"OOE6* uXb\*f4 ;44hrl# 	 $HRL&9rH   c                    t        d |D              ryddlm} t        |       D ]!  }t	        |      st        | ||              y |j                  ddd       y)zDPreserve human intent, not merely a synthetic user-role placeholder.c              3  2   K   | ]  }t        |        y wr[   )r  )r_   r   s     r   ra   z3_ensure_compressed_has_user_turn.<locals>.<genexpr>  s     
Dg )
Ds   Nr   )_fresh_compaction_message_copyr   zuContinue from the compressed conversation context above. This marker exists because no human user turn was available.)r   r   )rf   r  r  reversedr  r  r  )original_messages
compressedr  r   s       r    _ensure_compressed_has_user_turnr    si    

D
DDG-.  )$.w7  K rH   defaultF)approx_tokenstask_idrW   rX   c               "  @ABCD t        | dd      dk(  rt        | |||||      S |svt        | j                         t        t	        | j                        dd      }t        |      r6 || j                        r$t        | dd      }|s| j                  |      }||fS t        | dd      st        |        d	| _        t        |      }	t        t        | d
d            }
d}t        j                  d| j                  xs d|	|r|dnd| j                  |       | j                  t                t        | dd      @| j                  xs dDdAd}d}d}@3	 t#        @      }|%|s#	 @j&                  }t        |      st)        d      }	 t+        t        | dd      xs d      }t        | dd      }dB@Drt/        |       A|0dAt        j1                  dDt	        |      j2                  |       d}n@|2dAt        | dd      Dk7  rD| _        t        j1                  dD       d	}n	  |DA|      }|sx	 @j;                  D      }t        j1                  dD|       dAt        | dd      Dk7  rD| _        	 | j?                  d       t        | dd      }|s| j                  |      }||fS dCdd@ABCDfd}@RDrP	 tA        @D      }|rAt        j                  d D        |        t        | dd      }|s| j                  |      }||fS |sk| j                  }t        |       t        t	        |      dd      }t        |      r3 ||      r+ |        t        | dd      }|s| j                  |      }||fS 	 AtC        @DA||      BBjE                          d}| jF                  r7	 | jF                  jI                  |      }tK        |tL              rtO        |      }| j                  jP                  }tS        |||||!      }|jU                         red"|vrat        | j                  d#t	        | j                        j2                        }t        | d$d      |k7  r|| _+        t        j1                  d%|       tY        jZ                  |      }  ||fi |}!	 t        t        | j                  d&d            }"t        t        | j                  d'd            }#t        | j                  d(d      rz	 t        | j                  d)d      xs d*}$t        | d+d      |$k7  r|$| _/        | j?                  d,|$ d-       t        | dd      }|s| j                  |      }||f |         |        S |!| k(  rs|| k7  rtY        jZ                  |       |dd t        j                  d.| j                  xs d       t        | dd      }|s| j                  |      } |        ||f |        S |!sht        ja                  d/| j                  xs d       	 | j?                  d0       t        | dd      }|s| j                  |      } |        ||f |        S t        | j                  d)d      }%|%r-t        | d+d      |%k7  r|%| _/        | j?                  d1|% d2       ngt        | j                  d3d      }&t        | j                  d4d      }'|&r7|&|'f}(t        | d5d      |(k7  r#|(| _1        | j?                  d6|& d7|'xs d* d8       | jd                  jg                         })|)r|!ji                  d9|)d	d:       tk        ||!       | jl                  }*| jo                          |*#t        | d;d      tq        | |*      r
|*}+|*| _6        n| j                  |      }+|+| _6        | jr                  r	 | ju                  |       |
r9| jr                  jw                  | j                  |!       ty               | _=        d	}n	 | j}                  |       | jr                  j                  | j                        },| jr                  j                  | j                  d<       | j                  }-t        j                         j                  d=       d>t        j                         j                  dd?  | _        	 d@dAlGmH}.  |.| j                         	 d@dClKmL}/  |/| j                         d| _M        	 | jr                  j                  | j                  | j                  xs  t        j                  j                  dDdE      | j                  | j                  |-F       d	| _M        	 d@dHlSmT}1  |1|-| j                  d<I       |,rB	 | jr                  j                  |,      }3| jr                  j                  | j                  |3       | jr                  j                  | j                  |+       |
rd@| _X        nu| jr                  j                  | j                  |!       t        |!      | _X        | j                  | _Z        |!D 5ch c]  }5tK        |5t              rt        |5       c}5| _=        t               j                  dL      }6t        |6      xs |
}7|6xs | j                  xs d}8	 |7r^t        | j                  dP      rH| j                  j                  | j                  xs dd<|8t        | dQd      xs dEt        | dRd      S       	 |7r9| jF                  r-| jF                  j                  | j                  xs d|8dd<U       | j                  j                  };|;dWk\  r*| j                   dX|; dY}<|<| _c        | j                  |<       t        | dZd      rI	 | j                  d[| j                  xs d| j                  |6xs d|
| j                  j                  d\       || _e        t        |!|+xs d| j                  xs d^      }=|=| j                  _h        d_| j                  _i        d@| j                  _j        d	| j                  _k        |"rQt        t	        | j                        d`d      }>t        |>      r |>| j                  |#a       nd	| j                  _l        	 d@dblmmn}?  |?|       t        j                  dc| j                  xs d|	t        |!      |=d       |!|+f |        S # t$        $ r}|}Y d}~~d}~ww xY w# t$        $ r}|}Y d}~pd}~ww xY w# t(        t,        f$ r d}Y qw xY w# t$        $ rz}	 @j7                  DA       n,# t$        $ r }t        j9                  d|       Y d}~nd}~ww xY wdAt        j1                  dDt	        |      j2                  |       d}Y d}~cd}~ww xY w# t$        $ r d}Y ew xY w# t$        $ r Y 3w xY w# t$        $ r`}t        j1                  dDt	        |      j2                  |        |        t        | dd      }|s| j                  |      }||fcY d}~S d}~ww xY w# t$        $ r Y 
Ww xY w# t\        $ r	  |         w xY w#  |        w xY w# t$        $ r Y Mw xY w# t$        $ r Y |w xY w# t$        $ r! | j                  t        j                  dB<   Y w xY w# t$        $ r Y w xY w# t$        $ r}0t        j1                  dG|0|-       |-| _        	 d@dAlGmH}.  |.| j                         n,# t$        $ r  | j                  t        j                  dB<   Y nw xY w	 d@dClKmL}/  |/| j                         n# t$        $ r Y nw xY w	 | jr                  j                  |-       n# t$        $ r Y nw xY wd}-d	| _M         d}0~0ww xY w# t$        $ r!}2t        j9                  dJ|2       Y d}2~2Ld}2~2ww xY w# t,        t$        f$ r!}4t        j9                  dK|4       Y d}4~4;d}4~4ww xY wc c}5w # t$        $ rb}4t               j                  dL      (|
s&t        j1                  dM| j                  xs dN|4       nt        j1                  dO|4       Y d}4~4	d}4~4ww xY w# t$        $ r!}9t        j9                  dT|9       Y d}9~9d}9~9ww xY w# t$        $ r!}:t        j9                  dV|:       Y d}:~:d}:~:ww xY w# t$        $ r!}4t        j9                  d]|4       Y d}4~4d}4~4ww xY w# t$        $ r Y cw xY w#  |        w xY w)eu  Compress conversation context and split the session in SQLite.

    Args:
        agent: The owning :class:`AIAgent`.
        messages: Current message history (will be summarised).
        system_message: Current system prompt; used when compression needs a
            rebuilt cached prompt.
        approx_tokens: Pre-compression token estimate, logged for ops.
        task_id: Tool task scope (used for clearing file-read dedup state).
        focus_topic: Optional focus string for guided compression — the
            summariser will prioritise preserving information related to
            this topic.  Inspired by Claude Code's ``/compact <focus>``.
        force: If True, bypass any active summary-failure cooldown.  Set
            by the manual ``/compress`` slash command so users can retry
            immediately after an auto-compress abort.  Auto-compress
            callers use the default ``False``.

    Returns:
        ``(compressed_messages, new_system_prompt)`` tuple.  When
        compression aborts (aux LLM failed to produce a usable summary),
        returns the original messages unchanged and the existing system
        prompt — the session is NOT rotated.  Callers should detect the
        no-op via ``len(returned) == len(input)`` and stop the retry loop.
    api_modeNcodex_app_serverr   r!  rX   _automatic_compression_blocked_cached_system_prompt _compression_feasibility_checkedFTcompression_in_placezPcontext compression started: session=%s messages=%d tokens=~%s model=%s focus=%rnoner   unknown_session_dbr   z0compression lock API is present but not callable_compression_lock_ttl_secondsg     r@"_compression_lock_refresh_intervalug   compression lock lookup raised unexpectedly for session=%s (%s: %s) — skipping compression this cycle _last_compression_lock_error_sidu   compression lock subsystem unavailable for session=%s — proceeding without lock. This usually means a stale in-memory module after an update; restart the process (or `hermes update`) to resync.r   z8compression lock cleanup after failed acquire failed: %sul   compression lock acquisition raised unexpectedly for session=%s (%s: %s) — skipping compression this cycleu~   compression skipped: another path is compressing session=%s (holder=%s) — returning messages unchanged to avoid session fork"_last_compression_lock_warning_siduw   ⚠ Skipping concurrent compression — another path is already compressing this session. Will retry after it finishes.c                    ryd	 j                          rr	 j	                         yyyy# t        $ r } t        j                  d|        Y d} ~ Ad} ~ ww xY w# t        $ r }t        j                  d|       Y d}~yd}~ww xY w)z?Release the lock keyed on the OLD session_id (before rotation).NTz*compression lock refresher stop failed: %sz#compression lock release failed: %s)r   r   r3   r4   release_compression_lock)	_stop_err_rel_err_lock_db_lock_holder_lock_refresher_lock_released	_lock_sids     r   _release_lockz'compress_context.<locals>._release_lock  s     &V$$& I,N11)\J 3?I  VI9UUV
  NBHMMNs,   7 A# 	A  AA #	B,BBzecompression session ownership lookup failed for session=%s (%s: %s) - skipping compression this cyclezOcompression skipped: session=%s was already rotated by another compression path)rV   rW   rX   rY   rY   rl   '_last_memory_context_unsupported_enginezfcontext engine %s does not accept memory_context; continuing without provider-supplied summary context_last_compression_made_progress_last_summary_fallback_used_last_compress_aborted_last_summary_errorzunknown error!_last_compression_summary_warningu   ⚠ Compression aborted: uz   . No messages were dropped — conversation continues unchanged. Run /compress to retry, or /new to start a fresh session.uH   Compression made no progress (session=%s) — skipping boundary rewrite.zocontext compression returned an empty transcript; refusing to rotate session=%s so the parent remains resumableuo   ⚠ Compression returned an empty transcript. No session split was performed; conversation continues unchanged.u    ⚠ Compression summary failed: z%. Inserted a fallback context marker._last_aux_model_failure_model_last_aux_model_failure_error_last_aux_fallback_warning_keyu"   ℹ Configured compression model 'z
' failed (uS   ). Recovered using main model — check auxiliary.compression.model in config.yaml.r   )r   r   r   _memory_managerr@   z%Y%m%d_%H%M%Sr      r   )set_current_session_idHERMES_SESSION_ID)set_session_contextHERMES_SESSION_SOURCEcli)rD   sourcer   model_configparent_session_iduf   Compression child session create failed (%s) — rolling back to parent session %s to avoid an orphan.)migrate_goal_to_session)reasonz)Could not migrate goal on compression: %sz,Could not propagate title on compression: %sold_session_idzKCompression rotation aborted and rolled back to the parent session (%s): %sr   uK   Session DB compression split failed — new session will NOT be indexed: %son_session_startplatform_gateway_session_key)boundary_reasonrP  rR  conversation_idz1context engine on_session_start (compression): %s)rM  resetrO  z2memory manager on_session_switch (compression): %s   u   ⚠️  Session compressed u>    times — accuracy may degrade. Consider /new to start fresh.event_callbackzsession:compress)rR  rD   rP  in_placecompression_countz,event_callback error on session:compress: %s)system_prompttoolsr   record_completed_compaction)used_fallbackreset_file_dedupz^context compression done: session=%s messages=%d->%d rough_tokens=~%s awaiting_real_usage=truer   )or   &_compress_context_via_codex_app_serverr;   r   r(   r2   _build_system_promptr   r(  lenrA   r3   inforD   r   r   COMPACTION_STATUSr-   r   r%   rd   r{   re   rT   r   r   r/  r2  r4   get_compression_lock_holderr0  _emit_warningrG   rp   r   rD  on_pre_compressr   r   r	   compressrn   r   r;  copydeepcopyBaseExceptionr@  errorrC  _todo_storeformat_for_injectionr  r  r'  _invalidate_system_promptr"   r,  commit_memory_sessionarchive_and_compactr   _flushed_db_message_ids_flush_messages_to_session_dbget_session_titleend_sessionr   nowstrftimerQ   rR   rS   gateway.session_contextrF  rM   environhermes_loggingrH  _session_db_createdcreate_sessionrR  rB   _session_init_model_configreopen_sessionhermes_cli.goalsrN  get_next_title_in_lineageset_session_titleupdate_system_prompt_last_flushed_db_idxreplace_messages_flushed_db_message_session_idr   rP   localshasattrrQ  on_session_switchrZ  
log_prefixr   rX  r   r
   r\  last_compression_rough_tokenslast_prompt_tokenslast_completion_tokens%awaiting_real_usage_after_compression$_verify_compaction_cleared_thresholdtools.file_toolsr`  )Er   r   system_messager   r!  rW   rX   blockedexisting_prompt_pre_msg_countrY  compacted_in_place_try_acquire_lock_lock_lookup_error#_legacy_session_db_without_lock_apir:   	_lock_ttl_lock_refresh_interval_lock_acquired	_lock_err_release_errexisting_existing_spr:  _parent_already_rotated_session_errr5   rY   
_maybe_ctxri   compress_kwargsengine_namemessages_before_compressionr  _compression_made_progress_compression_used_fallback_errsummary_error_aux_fail_model_aux_fail_err_aux_keytodo_snapshotcached_system_promptnew_system_prompt	old_titlerP  rF  rH  _cs_errrN  	_goal_err	new_titleer   _old_sid_is_boundary_boundary_parent_ce_err_me_err_cc_cc_msg_compressed_estrecord_boundaryr`  r5  r6  r7  r8  r9  sE                                                                   @@@@@r   compress_contextr    s   T uj$'+==5'
 	
 -e.F.FG))*,

 G)A)A!B%e-DdKO""'"<"<^"L_,, 5<eD 	,E215.]N GE#95ABH 
KKZ"FN -=
9ekk	 
()0 umT2H  &BI"&L .2*/'	%2S3/
 %.Q)$,$I$I! 12)2J*&
'%)H%PYTYZ	 %U,PRVW@DO	/6)  LNN?4 23<<>P
 #N&  Lu@$G9T9B66  "N'!2|"2  #??	J NNU8
  LuBDIYV;D8''- #5*A4HL$99.I\))NN N( 		*&I)'#  #KK+
 O"5*A4HL$99.I\)) --
-j9,

 G!4O%e-DdKO""'"<"<^"L_,,8#<&O !!#   "22BB8L
j#.%<Z%HN ..777(#)
 !&6o&M!((U--.77K H$O AL=@ '+mmH&=# =_=
p
 &*E,,.OQVW&
" &*E,,.KUS&
" 5++-EuM u779NPTUhYh5"EtLPTT>BE;''3D6 :T T
  'u.EtL##(#=#=n#ML-` 	U 4466"mm,GHKKZ  *F #5*A4HL$99.IO\)~ 	{ LLD  *F
##X #5*A4HL$99.IO\)X 	U   8 8:OQUVuA4HMY:G7##6}o F: : &e&>&>@_aefO#E$<$<>]_cdM+];5"BDIXU;CE8''<_<M N)<_= >LL ))>>@(,0 
 	):>$::'') !,0$7?6u>RS 4*>E' % : :> J*;E'ju
 ++H5& %%99%:J:JJW 58EE1 *.&;;HE !& 1 1 C CEDTDT UI%%11%2B2BMR%*%5%5N*2,,.*A*A/*R)SSTUYU_U_UaUeUefhghUiTj'kE$KR.u/?/?@F+E,<,<= 16E--))88','7'7#(>>#cRZZ^^D[]b5c"'++).)I)I.< 9 Z 15E-
]L/@P@PYfg !\(-(9(9(S(ST](^I!--??@P@PR[\ !!66u7G7GIZ[12E.
 %%66u7G7GT14ZE.;@;K;KE8 (25#%gt4 75E1. 8<< 01H~1#=u'7'7=2
	W(@(@BT U((99$$*$1#3$UJ=F$+E3I4$P :  		X 5 5%%77$$*&6(	 8  &&88!8##$$?u EF G  *1E&w' 5*D1	P$$%7 % 4""'"2"2&.n" ().)A)A)S)S:  +='
 8+1r++%

 BQ  >68  3:;  7IM  F
 &%U--.-O
 (,,"<
 QU((M
	9W% 	l&Jq!	

 ,, 	e  	%!$	%  )%(") z" 	H  '55iN  LLR$ 
  $NtI77
 "'+'2    " ! B  	*NN=\"++ O"5*A4HL$99.I\))	*B  <   	N <  ^ %  % K:?:J:J

#67K %  % % T#^
 ,:(OV253C3CD( O>C>N>NBJJ':;O!J/0@0@A( ! !!!--<<^L( ! !)- 591K%\ % ]%PR[\\] !+I6 \"LL)WYZ[[\"5
  u 8<< 019(NN2383C3C3JsA
 NN#prstuJ  	WLLLgVV	W"  	XLLMwWW	X>  PKQOOPZ  		 	s  s &"s' 	t  (t 6v 8v0 >w  ;/x< +6x, !B9x< AAC8 3A*y AC8 ,A0AC8 $&AC8 y *AC8 EAC8 A3 ,y- =B#3 !y= :z* 3 A*z: 3 ~ '3 *A~; +A;3 &".3 <AC8 A AA! .;AB )AAC8 <AAB; B>AC8 AC( 5AC8 	s$ss$'	s=0s88s= tt	v"t54v5	u>uvu2vvv-,v-0	v=<v= 	x)	Ax$x)$x),	x95x< 8x99x< <y	yAC8 	y*&AC8 )y**AC8 -	y:63 9y::3 =&z'#3 &z''3 *	z733 6z773 :	~~"{;:~;&|$!~#|$$~(} ~	}
~}~}-,~-	}96~8}99~~3 	~8~3-3 3~883 ;+
& 3 &++3 3	AA<AAAAAC8 AAAAAC8 A!	ABA*ABB AC8 BABBAC8 B	AB8BAB3B-AC8 B3AB8B8AC8 B;	AC%CAC CAC8 C AC%C%AC8 C(	AC5C1AC8 C4AC5C5AC8 C8	ADr%  c          
        t        t        | dd      xs d      j                         }|dvrd}|s`|dk7  r[t        j	                  d|t        | dd      xs dt        |      |r|d	nd
       t        | dd      }|s| j                  |      }||fS t        | dd      }|Zt        j	                  dt        | dd      xs dt        |      |r|d	nd
       t        | dd      }|s| j                  |      }||fS t        j	                  dt        | dd      xs dt        |      |r|d	nd
       	 | j                  t               |j                         }	t        |	dd      r	 |j                          d| _        t        |	dd      st        |	dd      rC	 | j                  d|	j                          t        | dd      }|s| j                  |      }||fS 	 ddlm}
m}  |
| |	|d       t%        | j&                  d      r	 || |	       	 ddlm}  ||       t        j	                  dt        | dd      xs dt        |	dd      xs dt        |	dd      xs d       t        | dd      }|s| j                  |      }||fS # t        $ r Y Jw xY w# t        $ r Y ,w xY w# t        $ r Y w xY w# t        $ r t        j)                  dd       Y w xY w# t        $ r Y w xY w) a7  Route compaction to Codex app-server for Codex-owned threads.

    Hermes' normal compressor rewrites the local OpenAI-style transcript.
    That does not shrink the actual Codex app-server thread context. For this
    runtime, ask Codex to compact its own thread and keep Hermes' transcript
    unchanged.
     codex_app_server_auto_compactionnative>   offhermesr  r  z\codex app-server compaction skipped: mode=%s force=false (session=%s messages=%d tokens=~%s)rD   Nr*  r   r+  r'  _codex_sessionz_codex app-server compaction skipped: no active codex thread (session=%s messages=%d tokens=~%s)zFcodex app-server compaction started: session=%s messages=%d tokens=~%sshould_retireFinterruptedrm  u(   ⚠ Codex app-server compaction failed: r   )#_record_codex_app_server_compaction_record_codex_app_server_usageT)r   rX   update_from_responsez#codex compaction bookkeeping failed)exc_infor_  z>codex app-server compaction done: session=%s thread=%s turn=%s	thread_idr   turn_id)r   r   lowerr3   rd  rc  rb  r   re  r   compact_threadcloser  rg  rm  agent.codex_runtimer  r  r  r   r4   r  r`  )r   r   r  r   r!  rX   	auto_moder  codex_sessionresultr  r  r`  s                r   ra  ra    s;     98DPeg  33	Y(*2E<.8&M$1}Qy	
 "%)@$G#88HO((E#3T:M2E<.8&M$1}Qy	
 "%)@$G#88HO((
KKP|T*4fH -=
9	,- ))+Fv.	!  $v}e,0N	:6<<.I
 "%)@$G#88HO((K	

 	,'		
 5++-CD*5&95! KKH|T*4fT*0b	4(.B	 e%<dCO44^D_$$y    		  		2  K:TJK  sZ   1J $J J$ 3J3 K 	JJ	J! J!$	J0/J03 KK	K%$K%i@  )max_dimensionc                  | sy	 ddl m dd}d}dddfd	}dd}dd}| D ]B  }t        |t              s|j                  d      }	t        |	t              s7|	D ]  }
t        |
t              s|
j                  d      }|dk(  rQ|
j                  d
      } ||      } ||xs d      \  }}|rt        |t              r |||       |dz  }n|r|dz  }||dvr|
j                  d      }t        |t              r3|j                  dd      } ||      \  }}|r||d<   |dz  }|s|dz  }t        |t              s ||      \  }}|r||
d<   |dz  }|s|dz  }	 E |rt        j                  d|dz         |rt        j	                  d|dz         y|dkD  S # t        $ r }t        j	                  d|       Y d}~yd}~ww xY w)u  Re-encode all native image parts at a smaller size to recover from
    image-too-large errors (Anthropic 5 MB, unknown other providers).

    Mutates ``api_messages`` in place. Returns True if any image part was
    actually replaced, False if there were no image parts to shrink or
    Pillow couldn't help (caller should surface the original error).

    Strategy: look for ``image_url`` / ``input_image`` parts carrying a
    ``data:image/...;base64,...`` payload, plus Anthropic-native
    ``{"type": "image", "source": {"type": "base64", ...}}`` blocks.
    For each one whose encoded size exceeds 4 MB (a safe target that slides
    under Anthropic's 5 MB ceiling with header overhead) or whose longest side
    exceeds ``max_dimension``, write the base64 to a tempfile, call
    ``vision_tools._resize_image_for_vision`` to produce a smaller data
    URL, and substitute it in place.

    Non-data-URL images (http/https URLs) are not touched — the provider
    fetches those itself and the size limit is different.
    Fr   )_resize_image_for_visionu6   image-shrink recovery: vision_tools unavailable — %sNi  @ c                2   	 ddl }ddl}| j                  d      \  }}}|r| j                  d      syddlm} |j                  |j                  |j                  |                  5 }|j                  cddd       S # 1 sw Y   yxY w# t        $ r Y yw xY w)zReturn ``(width, height)`` of a base64 data URL, or None on failure.

        Soft-depends on Pillow; returns None (caller falls back to a
        bytes-only check) if Pillow is missing or the payload is corrupt.
        r   Nr   data:)Image)base64io	partitionr   PILr  openBytesIO	b64decodesizer   )data_url_b64_dim_io_dimheader_dr   data_d	_PILImage_imgs           r   _decode_pixelsz:try_shrink_image_parts_in_messages.<locals>._decode_pixels  s    
	% "*"4"4S"9Ha!4!4W!=.0B0B60J KL !PTyy! ! ! 		s4   0B
 5B
 (A>4	B
 >BB
 B
 
	BBurlc                   t        | t              r| j                  d      syt        |       kD  }|rdnd}|s |       }|yt	        |      k  ryd}d}	 | j                  d      \  }}}d}|j                  d      rB|t        d      d j                  d	d
      d   j                         }|j                  d      r|}ddl}	|	j                  |      }
dddddddj                  |d      }t        j                  d|d      }	 |j                  |
       |j                           t        |j                         |      }	 t        |j                         j#                  d       |sy|dk(  r5t        |      t        |       k\  ry |      }|t	        |      kD  ry|dfS  |      }|t	        |      k  r|dfS yt        |      t        |       k\  ry|dfS # t$        $ r Y w xY w# 	 t        |j                         j#                  d       w # t$        $ r Y w w xY wxY w# t$        $ r&}t&        j)                  d|       d|dufcY d}~S d}~ww xY w)u  Return ``(resized_url, unshrinkable)`` for a data URL.

        ``resized_url`` is a smaller/dimension-correct data URL, or None when
        no rewrite was applied.  ``unshrinkable`` is True only when the image
        exceeded a constraint (byte-size or dimensions) and the resize failed
        to satisfy *that same* constraint — so the caller knows retrying is
        pointless even if a different image in the request shrank.
        r  )NFbytesNT	dimensionr   
image/jpeg;rs   r   image/z.pngz.gifz.webpz.jpgz.bmp)z	image/pngz	image/gifz
image/webpr  z	image/jpgz	image/bmphermes_shrink_F)prefixsuffixdelete)	mime_typemax_base64_bytesr  )
missing_ok)NTu.   image-shrink recovery: re-encode failed — %s)r   r   r   rc  ry   r  splitr   r  r  rB   tempfileNamedTemporaryFilewriter  r   rl   unlinkr   r3   r   )r  needs_shrinktriggered_bydimsheaderr   datamime	mime_part_b64rawr  tmpresizednew_dimsr:   r  r  r  target_bytess                   r   _shrink_data_urlz<try_shrink_image_parts_in_messages.<locals>._shrink_data_url  s    #s#3>>'+B 3x,.".wD "#&D|"4yM)"L&LD	2!mmC0OFAtD  )"3w<=177Q?BHHJ	''1$D!..&C#&$6 c$  --'uC		#		2N"%1"/	N))T): !w&w<3s8+% *'2'CMM,I%~% &g.H#x=M1"E>)! 7|s3x'!E>!K ! N))T):  L  	2NNKSQT111	2s   B0H/ 
A G5 %G& 0H/ 3H/ H/ )H/ -H/ 
H/ "H/ &	G2/H/ 1G22H/ 5H,7%HH,	H)&H,(H))H,,H/ /	I8IIIrK  c                "   t        | t              r| j                  d      dk7  ry | j                  d      }t        |t              r|sy t        | j                  d      xs d      j	                         }|j                  d      sd}d| d| S )	Nr(   r  r  
media_typer  r  r  z;base64,)r   r   rB   r   r   r   )rK  r  r  s      r   _source_to_data_urlz?try_shrink_image_parts_in_messages.<locals>._source_to_data_url  s    &$'6::f+=+Izz&!$$DL1A\BHHJ
$$X.%Jzl(4&11rH   c                    |j                  d      \  }}}d}|j                  d      rB|t        d      d  j                  dd      d   j	                         }|j                  d      r|}d| d	<   || d
<   || d<   y )Nr   r  r  r  rs   r   r  r  r(   r  r  )r  r   rc  r  r   )rK  r  r   r   r  r  	candidates          r   _write_data_url_to_sourcezEtry_shrink_image_parts_in_messages.<locals>._write_data_url_to_source  s    ",,S14!
W%s7|}-33C;A>DDFI##H-&
!v)|vrH   r   r(   imager   rs   >   	image_urlinput_imager  zGimage-shrink recovery: re-encoded %d image part(s) to fit under %.0f MBi   u   image-shrink recovery: %d oversized image part(s) could not be shrunk under %.0f MB — not retrying (would re-send rejected payload))r  r   r   zOptional[tuple])r  r   r   tuple)rK  r   r   r  )rK  r   r  r   r   r   )tools.vision_toolsr  r   r3   r   r   r   rB   r   r   rd  )api_messagesr  r:   changed_countunshrinkable_oversizedr
  r  r  r   r   r   ptyperK  r  r  unshrinkableimage_valuer  r  r	  s    `               @@@r   "try_shrink_image_parts_in_messagesr  W  s-   0 ? #L
 M $g2 g2R	2	  '0#t$'')$'4( !	0DdD)HHV$E(+)&1(8(C%z&$7-fg>!Q&M!*a/*88((;/K +t,!ooeR0(8(=%)0K&!Q&M!*a/*K-(8(E%(/D%!Q&M!*a/*C!	0'0R U<;7	
 
 	U"LK$@	

 1  OQTUs   F0 0	G9GG)re  COMPACTION_STATUS_MARKERr   r   r  r  )r   r   r   zOptional[Tuple[str, str]])r   r   r   r   r   rA   )r+   r   r   rA   )r5   r   r   r   )rC   r   rD   r   r   rA   )r   r   r   r   )ri   r   rV   Optional[int]rW   r  rX   rA   rY   r   r   r   )r   r   r   r   )r   r   r   r   r   zOptional[list])r   r   r   r   )r   r   r   rA   )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   rW   r  rX   rA   r   Tuple[list, str])r   r   r   r   r  r  r   r  r!  r   rX   rA   r   r  )r  r   r  r}   r   rA   )0__doc__
__future__r   rj  r)   loggingrM   r  rQ   rL   r   pathlibr   typingr   r   r   agent.context_enginer	   r   r
   	getLoggerr   r3   r  re  r   r"   r-   r;   rG   rT   rn   rp   r   r   r   r   r   r   r  r  r  r  r  ra  r  __all__r   rH   r   <module>r(     s
  8 #    	      ' ' 8 >			8	$ 0 '((bc 
8"J.X 
($U$U "$U 	$U
 $U $U 
$UNL L^D
N$. 
 C.:&:R6 $(!%bbb b
 !b b b b bT $(u%u%u% "u%
 !u% u% u% u%v || | 
	|~rH   