+
    „WÝjùÖ  ã            
      ó  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
HtHt ^ RIHtHtHtHtHtHtHtHtHt ]P0                  ! R4      tRtR]! RR	4       R
]! RR4       R]P6                  ! RR7       R]! R4       R2	tRtR R ltR R ltRt R*t!R R lt"]#! 0 R+m4      t$Rt%Rt&R]%P7                  RR7      ,           R,           t'R R  lt(R!]%P7                  R"R7       R#]%P7                  R$R7       R%]! R&R'4       2t) ! R( R)4      t*R# ),zÝCompression lineage, cooldown/streak counters, locks and turn leases for SessionDB.

Mixin bound onto ``SessionDB`` via the MRO, built on its ``_read_ctx`` /
``_execute_write`` / ``_write_sql`` / ``_read_one`` primitives.)ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚTuple)	Ú_BOUNDARY_END_REASONSÚ_COMPRESSION_LOCK_ROW_SQLÚ_ENDED_ROW_SQLÚ_ended_by_compressionÚ_RESET_CHILD_SQLÚ_non_continuation_child_sqlÚ_sql_json_extractÚ_sql_session_last_activeÚis_automatic_end_reasonÚhermes_statez_SELECT compression_failure_cooldown_until, compression_failure_error FROM sessions WHERE id = ?a  
                    SELECT child.id
                    FROM sessions parent
                    JOIN sessions child ON child.parent_session_id = parent.id
                    WHERE parent.id = ?
                      AND parent.end_reason = 'compression'
                      AND zchild.model_configz$._branched_fromz# IS NULL
                      AND z$._delegate_fromz( IS NULL
                      AND NOT (Úchild)ÚaaI  )
                      AND COALESCE(child.source, '') != 'tool'
                    ORDER BY
                      CASE
                        WHEN child.end_reason = 'compression' THEN 0
                        WHEN child.ended_at IS NULL THEN 1
                        ELSE 2
                      END,
                      zˆ DESC,
                      child.started_at DESC,
                      child.id DESC
                    LIMIT 1
                    g     õ@c               ó    € V ^8„  d   QhRRRR/# )é   ÚexistsÚboolÚreturnúdict[str, Any]© )Úformats   "ÚLC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_state_compression.pyÚ__annotate__r   9   s   € ÷ mñ m˜$ð m¸.ñ mó    c                ó6   € R T RVe   \        V4      RV/# RRV/# )Úsession_existsÚcooldown_untilNÚerror©Úfloat)r   r!   r"   s   &&&r   Ú_cooldown_rowr%   9   s=   € Ø˜fØ°~Ò7Qœe NÓ3Ð]dÐfkðmð mØW[Ð]dÐfkðmð mr   c               ó4   € V ^8„  d   QhRRRRRRRRRRRRR	R
/# )r   ÚtableÚstrÚkey_colÚkeyÚholderÚnowr$   Ú
expires_atr   ztuple[bool, Optional[str]]r   )r   s   "r   r   r   >   sI   € ÷ Mñ M #ð M°ð M¸#ð MÀsð MÐQVð MÐdið MØ9ñMr   c                ó¦  € RpV P                  RV RV R2V34      P                  4       p	V	eH   V! V	R,          V	R,          4      '       d+   V P                  RV RV R2W9R,          34       V	R,          pV P                  R	V R
V R2W4WV34       V P                  RV RV R2V34      P                  4       p
V
RJ;'       d    V
R,          V8H  V3# )zëSingle-transaction lease claim: DELETE a stale holder's row (``stale(holder,
expires_at)``), INSERT OR IGNORE ours, then SELECT to confirm ownership (INSERT OR
IGNORE gives no rowcount signal). Returns ``(acquired, reclaimed_holder)``.NzSELECT holder, expires_at FROM z WHERE z = ?r+   r-   zDELETE FROM z = ? AND holder = ?zINSERT OR IGNORE INTO z (z6, holder, acquired_at, expires_at) VALUES (?, ?, ?, ?)zSELECT holder FROM )ÚexecuteÚfetchone)Úconnr'   r)   r*   r+   r,   r-   ÚstaleÚreclaimed_holderÚrowÚowners   &&&&&&&&   r   Ú_claim_lease_rowr6   >   sù   € ð
 ÐØ
�,‰,Ð8¸¸¸wÀwÀiÈtÐTÐWZÐV\Ó
]×
fÑ
fÓ
h€CØ
‚™5  X¥°°LÕ0A×BÒBØ�‰�| E 7¨'°'°Ð:MÐNÐQTÐZbÕVcÐPdÔeØ˜x�=ÐØ‡L�LØ
    r¨'¨Ð2hÐiØ	�cÐ&ô(ð �L‰LÐ.¨u¨g°W¸W¸IÀTÐJÈSÈFÓS×\Ñ\Ó^€EØ˜Ð×:Ð:  x¥°FÑ!:Ð<LÐLÐLr   iè  c               ó    € V ^8„  d   QhRRRR/# ©r   Ú
session_idr(   r   z	list[str]r   )r   s   "r   r   r   Z   s   € ÷ ñ ¨ð °iñ r   c                ó   € T pV'       d   V.M. p\        V4      p\        \        4       FP  pV! V4      pVe
   VR,          MRpV'       d   Wt9   d   Vu # VP                  V4       TpVP	                  V4       KR  	  V# )zcRoot-first ids from *session_id* through its tip; ``step(id)`` returns the ``_CHAIN_STEP_SQL`` row.NÚid)ÚsetÚrangeÚ
_CHAIN_CAPÚaddÚappend)r9   ÚstepÚcurrentÚchainÚseenÚ_r4   Úchild_ids   &&      r   Ú_walk_compression_chainrG   Z   su   € à€Gß ˆW‰I b€EÜˆu‹:€Dô ”:ÖˆÙ�7‹mˆØ #¢�3�t–9°Tˆß˜8Ô+ØŠLØ�‰�ÔØˆØ�‰�XÖñ ð €Lr   z/COALESCE({col}, '') IN ('', 'unknown', 'local')zCSELECT parent_session_id, created_source FROM sessions WHERE id = ?a‰  
    WITH RECURSIVE up(pid, n) AS (
        SELECT parent_session_id, 1 FROM sessions WHERE id = ?
        UNION ALL
        SELECT s.parent_session_id, up.n + 1 FROM up JOIN sessions s ON s.id = up.pid
        WHERE s.end_reason = 'compression' AND s.created_source = ? AND up.n < ?
    )
    SELECT 1 FROM up CROSS JOIN sessions s ON s.id = up.pid
    WHERE s.end_reason = 'compression' AND zs.created_source)Úcolz
    LIMIT 1
c               ó    € V ^8„  d   QhRRRR/# ©r   r9   r(   r   ÚNoner   )r   s   "r   r   r   †   s   € ÷ Dñ D°#ð D¸$ñ Dr   c                ó”  € V P                  \        V34      P                  4       pV'       d
   VR,          MRpV\        9   d   R# V P                  \        W\
        34      P                  4       f   R# YR,          rT\        \
        4       F¸  pT;'       d&    V P                  \        V34      P                  4       pV'       d   VR,          . \        OVN59  d    R# V P                  \        V34      P                  4       pVe   VR,          V8w  d    R# VR,          V8w  d   V P                  RW534       YWR,          rTKº  	  R# )a-  Copy *session_id*'s ``created_source`` onto compression ancestors that have none.

A list page shows a compressed conversation as its root, painted as the tip, and filters on
the root's ``created_source``. Automatic compression publishes the child before any writer
knows the surface, so the turn's usage write stamps only the tip. Stamping the chain here,
in that same transaction, keeps the root matchable without a list-time chain walk. Each hop
must be the parent's preferred continuation (``_CHAIN_STEP_SQL``); ``unknown`` and ``local``
count as unset, as in the creator upsert. An ancestor already on the same surface is walked through
(a NULL root behind a stamped mid segment still gets stamped); another surface stops it.
A chain with no unset ancestor returns after one query (``_UNSET_ANCESTOR_SQL``).
Úcreated_sourceNÚparent_session_idr;   z3UPDATE sessions SET created_source = ? WHERE id = ?)r/   Ú_CREATED_ROW_SQLr0   Ú_UNSET_CREATED_SOURCESÚ_UNSET_ANCESTOR_SQLr>   r=   Ú_CHAIN_STEP_SQL)	r1   r9   r4   ÚsurfacerB   Ú	parent_idrE   ÚparentrA   s	   &&       r   Ústamp_compression_ancestorsrV   †   s  € ð �,‰,Ô'¨*¨Ó
7×
@Ñ
@Ó
B€Cß'*ˆcÐ"Ö#°€GØÔ(Ô(ÙØ‡|�|Ô'¨*¼zÐ)JÓK×TÑTÓVÒ^ÙØ#Ð)<Õ%=ˆYÜ”:ÖˆØ×VÐV˜tŸ|™|Ô,<¸y¸lÓK×TÑTÓVˆß˜Ð 0Õ1Ð9[Ô;QÐ9[ÐSZÑ9[Ô[ÚØ�|‰|œO¨i¨\Ó:×CÑCÓEˆØŠ<˜4 �:¨Ô0ÚØÐ"Õ# wÔ.Ø�L‰LÐNÐQXÐPdÔeØ&Ð/BÕ(C’ó r   z•
    SELECT child.id FROM sessions parent JOIN sessions child ON child.parent_session_id = parent.id
    WHERE parent.end_reason = 'compression' AND zparent.created_sourcez
      AND NOT zchild.created_sourceÚ
zchild.z	parent.idc                  ó¶  € ] tR t^³tRtRR/R R lltR R ltR R	 ltR
 R ltR R lt	RRRRRRRRRRRRRRRRRRRRRR/R R llt
RRRRRRRRRRRRRRRRRRRRRR/R R lltR  R! ltRqR" R# lltR$ R% ltR& R' ltR( R) ltR* R+ ltR, R- ltR. R/ ltR0 R1 ltR2 R3 ltR4 R5 ltR6 R7 ltR8 R9 ltR: R; ltR< R= ltR> R? ltR@ RA ltRrRB RC lltRrRD RE lltRF RG ltRH RI lt RJ RK lt!RLRRR/RM RN llt"RLRRORPRQRRRSRRTRURVRRWRXRYR/RZ R[ llt#R\ R] lt$RLRRR/R^ R_ llt%R` Ra lt&Rb Rc lt'Rd Re lt(Rf Rg lt)Rh Ri lt*Rj Rk lt+Rl Rm lt,Rn Ro lt-Rpt.R# )sÚSessionCompressionMixinzECompression lineage, cooldown/streak counters, locks and turn leases.Ú
patience_sNc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r9   r(   Ú
provenancerZ   úOptional[float]r   úOptional[str]r   )r   s   "r   r   Ú$SessionCompressionMixin.__annotate__¶   s,   € ÷ )ñ )Øð)Ø.1ð)Ø?Nð)à	ñ)r   c               ó†   a a€ S'       g   R# V V3R lpS P                  WCR7      pVe   \        P                  RSWR4       V# )a  Clear an explicit-close stamp (``tui_close``, ``cli_close``, ``webhook_complete``, ...) from a
session a HOST has just proven is still routed to it, returning the reason cleared or None (#106459).
Narrow twin of ``reopen_session()``: automatic stamps are left to publish (#88197); ``compression``,
boundary (reset reasons, CLI ``new_session``) and stamps with a published continuation own lineage
elsewhere and are never touched. The UPDATE is conditional on the exact stamp read, so a close
landing between read and write survives.

Only the routing host can make this call. Publication cannot: ``end_session()`` is first-stamp-wins,
so a close made during a turn that began on a stale stamp is a no-op write. Turn-lease admission
cannot: the TUI starts its worker before it reaches ``run_conversation()``, so ``session.close`` can
stamp ``tui_close`` in between and a late lease would clear a deliberate close. Call it under the
lock that makes the host's registry claim atomic with its teardown (#54878 on the routing table).Nc                óÆ  <€ V P                  \        S34      P                  4       pVe   VR,          f   R # VR,          p\        V4      '       g   VR8X  g   V\        9   d   R # V P                  RSP
                  P                  RR7      ,           R,           S3^,          4      P                  4       pVe   R # V P                  RSVR,          V34       \        V4      # )	NÚended_atÚ
end_reasonÚcompressionz2SELECT 1 FROM sessions WHERE parent_session_id = ?Ú ©Úaliasz LIMIT 1zgUPDATE sessions SET ended_at = NULL, end_reason = NULL WHERE id = ? AND ended_at = ? AND end_reason = ?)r/   r
   r0   r   r   Ú"_NON_CONTINUATION_CHILD_FILTER_SQLr   r(   )r1   r4   ÚreasonÚ
supersededÚselfr9   s   &   €€r   Ú_doÚ@SessionCompressionMixin.reopen_if_explicitly_closed.<locals>._doÈ   sÚ   ø€ Ø—,‘,œ~°
¨}Ó=×FÑFÓHˆCØŠ{˜c *�oÒ5ÙØ˜Õ&ˆFÜ& v×.Ò.°&¸MÔ2IÈVÔWlÔMlÙØŸ™ØDØ×9Ñ9×@Ñ@ÀrÐ@ÓJõKØMWõXà� Õ!ó#÷ $,¡8£:ð ð Ò%ÙØ�L‰LðCà˜S �_¨fÐ5ô7ô �v“;Ðr   ©rZ   z‚Session %s carried a stale %r end stamp while %s; cleared so the conversation can compress and a later close is recorded (#106459))Ú_execute_writeÚloggerÚwarning)rk   r9   r\   rZ   rl   ri   s   ff$$  r   Úreopen_if_explicitly_closedÚ3SessionCompressionMixin.reopen_if_explicitly_closed¶   sK   ù€ ÷ Ùö	ð$ ×$Ñ$ SÐ$Ó@ˆØÒÜ�N‰NðCØDNÐPVôdð ˆr   c               ó   € V ^8„  d   QhRR/# ©r   r   Úintr   )r   s   "r   r   r_   á   s   € ÷ (ñ (°ñ (r   c                ó*   € R pV P                  V4      # )aõ  Stamp the unset ancestors of chains compressed before write-time stamping from their
stamped segments, through ``stamp_compression_ancestors`` (same edge checks; a known value
is never replaced). One write transaction and idempotent, so the owner runs it on every
start: a store with nothing to repair pays one scan of sessions under the write lock, plus
a one-hop walk per stamped child of an unset compression parent that the walk does not
follow (a non-preferred sibling). Returns the rows stamped.c                ó¸   € V P                   pV P                  \        4      P                  4        F  p\	        WR ,          4       K  	  V P                   V,
          # )r;   )Útotal_changesr/   Ú_UNSTAMPED_EDGE_CHILD_SQLÚfetchallrV   )r1   Úbeforer4   s   &  r   rl   ÚDSessionCompressionMixin.stamp_legacy_compression_chains.<locals>._doè   sH   € Ø×'Ñ'ˆFØ—|‘|Ô$=Ó>×GÑGÖI�Ü+¨D°dµ)Ö<ñ Jà×%Ñ%¨Õ.Ð.r   ©ro   )rk   rl   s   & r   Ústamp_legacy_compression_chainsÚ7SessionCompressionMixin.stamp_legacy_compression_chainsá   s   € ò	/ð
 ×"Ñ" 3Ó'Ð'r   c               ó    € V ^8„  d   QhRRRR/# )r   rN   r(   r   úOptional[dict[str, Any]]r   )r   s   "r   r   r_   ï   s   € ÷ Kñ K¸Sð KÐE]ñ Kr   c           	     óð  € V'       g   R# V P                  4       ;_uu_ 4       p\        VP                  \        V34      P	                  4       4      '       g    RRR4       R# VP                  RV P
                  P                  RR7      ,           R,           V3^,          4      P                  4       pRRR4       \        X4      ^8X  d   V P                  V^ ,          4      # R#   + '       g   i     L:; i)zÛThe unique live direct child of a compression-ended session, else None. A stale
agent whose parent was rotated elsewhere may recover only when the lineage names
exactly one live continuation; more than one fails closed.Nad  
                SELECT s.*,
                       COALESCE(sp.prompt, s.system_prompt)
                           AS _system_prompt_resolved
                FROM sessions s
                LEFT JOIN system_prompts sp ON sp.hash = s.system_prompt_hash
                WHERE s.parent_session_id = ?
                  AND s.ended_at IS NULL
                zs.rf   zS
                ORDER BY s.started_at ASC
                LIMIT 2
                )
Ú	_read_ctxr   r/   r
   r0   rh   r   r{   ÚlenÚ_session_row_dict)rk   rN   r1   Úrowss   &&  r   Úfind_live_compression_childÚ3SessionCompressionMixin.find_live_compression_childï   sÒ   € ÷ !ÙØ�^‰^×Ô Ü(¨¯©´nÐGXÐFZÓ)[×)dÑ)dÓ)f×gÒgØ÷ Ñð —<‘<ðð ×9Ñ9×@Ñ@ÀtÐ@ÓLõ	Mðõð #Ð$ qÕ(ó÷  ‰h‹jð! ÷ ô( 36°d³)¸q´.ˆt×%Ñ% d¨1¥gÓ.ÐJÀdÐJ÷) ×ús   £6C%Á#AC%Ã%C5	c               ó    € V ^8„  d   QhRRRR/# )r   r9   r(   r   r   r   )r   s   "r   r   r_     s   € ÷ 7.ñ 7.¸cð 7.Àdñ 7.r   c                ó\   a a€ S'       g   R# V V3R lp\        S P                  V4      4      # )zæReopen a compression parent only when no continuation was published (older
builds could leave a closed parent after an interrupted handoff). Conservative:
an active lease or any canonical child means another path owns the lineage.Fc                óx  <€ \        V P                  \        S34      P                  4       4      '       g   R # V P                  RSP                  P                  RR7      ,           R,           S3^,          4      P                  4       pVe   R # \        P                  ! 4       pV P                  \        S34      P                  4       pVeO   VR,          pVe   \        V4      V8¼  d   R # V P                  RSVR,          V34      pVP                  ^8w  d   R # V P                  RS34      pVP                  ^8H  # )	Fzt
                SELECT 1
                FROM sessions
                WHERE parent_session_id = ?
                re   rf   z)
                LIMIT 1
                r-   zTDELETE FROM compression_locks WHERE session_id = ? AND holder = ? AND expires_at = ?r+   z{UPDATE sessions SET ended_at = NULL, end_reason = NULL WHERE id = ? AND ended_at IS NOT NULL AND end_reason = 'compression')
r   r/   r
   r0   rh   r   ÚtimeÚ_LOCK_ROW_SQLr$   Úrowcount)	r1   r   r,   Úlock_rowr-   ÚdeletedÚupdatedrk   r9   s	   &      €€r   rl   ÚHSessionCompressionMixin.reopen_orphaned_compression_session.<locals>._do  s3  ø€ Ü(¨¯©´nÀzÀmÓ)T×)]Ñ)]Ó)_×`Ò`Ùà—L‘Lðð
 ×9Ñ9×@Ñ@ÀrÐ@ÓJõKðõð � Õ!ó÷ ‰h‹jð ð Ò Ùô —)’)“+ˆCØ—|‘|¤M°J°=ÓA×JÑJÓLˆHØÒ#Ø% lÕ3�
ØÒ%¬¨zÓ):¸cÔ)AÙ ØŸ,™,ØjØ ¨(Õ!3°ZÐ@óB�ð ×#Ñ# qÔ(Ù Ø—l‘lðWà�óˆGð  ×#Ñ# qÑ(Ð(r   )r   ro   ©rk   r9   rl   s   ff r   Ú#reopen_orphaned_compression_sessionÚ;SessionCompressionMixin.reopen_orphaned_compression_session  s)   ù€ ÷ Ùö0	)ôb �D×'Ñ'¨Ó,Ó-Ð-r   c               ó   € V ^8„  d   QhRR/# )r   r   rK   r   )r   s   "r   r   r_   D  s   € ÷ -
ñ -
Ø]añ-
r   c               ó  a€ ^ RI Hp V! VR,          4      P                  4        UUu/ uF  w  rÍV\        9   g   K  WÍbK  	  ppp/ VCS;'       g    / CoV P	                  W4      p\
        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       * p^ RIHp V! VR,          4      ;'       g	    V! V4      pTP                  RYETTS'       d   \        P                  ! S4      MR	YòR
,          Y9;'       g
    VR,          VR,          VR,          T
;'       g"    VR,          ;'       g    V P                  4       VR,          VR,          VR,          VR,          VR,          VR,          VR,          V'       d   \        VR,          ;'       g    ^ 4      M^ \        P                  ! 4       V'       d   VR,          ;'       g    ^ M^ V'       d   VR,          ;'       g    ^ M^ 34       R	# u uppi )a
  INSERT the compression child's ``sessions`` row copied from *parent*. Same contract as
_insert_session_row's compression-fork backfill: the child stays on the parent's profile and keeps
gateway routing/origin columns; no owner on either side -> this store's profile.)Ú_parse_model_configÚmodel_configc              3  ó@   <"  € T F  qS;'       g    / 9   x € K  	  R # 5i©Nr   )Ú.0Úkrš   s   & €r   Ú	<genexpr>ÚESessionCompressionMixin._publish_child_session_row.<locals>.<genexpr>P  s   øé € ÐdÑBc¸Q \×%7Ð%7°RÖ8ÓBcùs   ƒ‘TF)Úcreated_surfacerM   a
  INSERT INTO sessions (
                   id, source, created_source, model, model_config, system_prompt,
                   system_prompt_hash, tool_names,
                   parent_session_id, cwd, git_branch, git_repo_root,
                   profile_name, user_id, session_key, chat_id, chat_type,
                   thread_id, display_name, origin_json, pinned, started_at,
                   archived, auto_archived
                ) VALUES (?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)NÚ
tool_namesÚcwdÚ
git_branchÚgit_repo_rootÚprofile_nameÚuser_idÚsession_keyÚchat_idÚ	chat_typeÚ	thread_idÚdisplay_nameÚorigin_jsonÚpinnedÚarchivedÚauto_archived)Ú_branched_fromÚ_reset_from)Úhermes_state_sessionsr™   ÚitemsÚ_CONVERSATION_MODEL_CONFIG_KEYSÚ_store_system_promptÚanyÚgateway.session_policyr¡   r/   ÚjsonÚdumpsÚ_own_profile_namerv   r�   )rk   r1   rU   rN   Úchild_session_idÚsourceÚmodelrš   Úsystem_promptr£   r¦   r™   r*   ÚvalueÚcarriedÚsystem_prompt_hashÚcontinuationr¡   rM   s   &&&$$$$d$$$        r   Ú_publish_child_session_rowÚ2SessionCompressionMixin._publish_child_session_rowD  s¿  ø€ õ
 	>Ù0CÀFÈ>ÕDZÓ0[×0aÑ0aÔ0cô >Ñ0c¡* #ØÔ<Ñ<ô �3’:Ñ0cˆñ >à:˜'Ð: l×&8Ð&8°bÐ:ˆØ!×6Ñ6°tÓKÐ÷ ›3ÔdÑBcÓdŸ3Ÿ3š3ÔdÑBcÓdÓdÔdˆõ 	;Ù(¨Ð0@Õ)AÓB×]Ð]ÁoÐV\ÓF]ˆð 	�‰ðhð !¨.¸%×]iÄÇÂÈLÔAYÐosØ"¨<Õ$8Ð:K×MaÐMaÐTZÐ[`ÕTaÐciÐjvÕcwØ�Õ'Ø×RÐR  ~Õ 6×RÐR¸$×:PÑ:PÓ:RØ�yÕ! 6¨-Õ#8¸&ÀÕ:KÈVÐT_ÕM`Ø�{Õ# V¨NÕ%;¸VÀMÕ=Rç.:”�F˜8Õ$×)Ð)¨Ô*ÀÄ4Ç9Â9Ã;÷ .:�˜
Õ#×(Ð( qø¸qß2>�˜Õ(×-Ð-¨AøÀAðGö	
ùó#>s
   ¨G=¼G=r¾   rš   r¿   r£   r¦   Úcompression_lock_holderÚrequire_compression_leaseTÚrequire_lease_refreshFÚlease_ttl_secondsç     Àr@Ú	watermarkÚwatermark_ceilingc                óX   € V ^8„  d   QhRRRRRRRRRRR	R
RRRRRRRRRRRRRRRRRRRR/# ©r   rN   r(   r¼   r½   Úmessageszlist[dict[str, Any]]r¾   z
str | Nonerš   zdict[str, Any] | Noner¿   r£   r¦   rÆ   rÇ   r   rÈ   rÉ   r$   rË   úOptional[int]rÌ   r   rK   r   )r   s   "r   r   r_   s  s»   € ÷ vñ vØ$'ðvØ;>ðvØHKðvà&ðvà/9ðvàPeðvð "ðvð 0:ðvð Q[ðvð ",ð	vð PTð	vð
  $ðvð
 AFðvð !ðvð =Jðvð VZñvr   c               óp   a aaaaaaaaa	a
aaaaa€ S P                  VV
VVVVVVV	VVV VVVV3R lS4       R# )u6  Atomically close a parent and publish its durable compression child: closure, child row, and
handoff commit in one transaction, so readers see the live parent or a complete child, never an
ended parent with a missing/empty child. *watermark* (the parent's highest row already represented
in the handoff: its ``get_active_message_watermark`` at compression start, or the newest row of an
adopted durable snapshot): parent rows with ``id > watermark`` â€” appends landed during the slow
summary â€” are column-cloned into the child AFTER the handoff. *watermark_ceiling* bounds the clone:
the rotation path flushes its OWN transcript to the parent just before publishing and those rows are
already in the handoff, so only ``(watermark, watermark_ceiling]`` is foreign tail (``None`` =
unbounded). *require_lease_refresh* +
*compression_lock_holder* refreshes the lease on the same ``conn`` before the expiry check (no
TOCTOU window), so a refresher that died on transient DB errors gets one last chance.

See #75316.
``None`` = unbounded (no internal flush happened). See #47202.
c                óF   <€ SP                  V SSSSSSSSS	SS
SSSSR 7      # ))rN   r¼   r½   rÏ   r¾   rš   r¿   r£   r¦   rÆ   rÇ   rÈ   rÉ   rË   rÌ   )Ú"_publish_compression_child_on_conn)r1   r¼   rÆ   r£   rÉ   rÏ   r¾   rš   rN   r¦   rÇ   rÈ   rk   r½   r¿   rË   rÌ   s   &€€€€€€€€€€€€€€€€r   Ú<lambda>ÚCSessionCompressionMixin.publish_compression_child.<locals>.<lambda>‰  sC   ø€ °D×4[Ñ4[ØÐ$5ÐHXÐagØ U¸ÐUbØ ,ÐH_Ø&?ÐWlØ/¸9ÐXið 5\ô 5kr   N)Ú_execute_transcript_write)rk   rN   r¼   r½   rÏ   r¾   rš   r¿   r£   r¦   rÆ   rÇ   rÈ   rÉ   rË   rÌ   s   fdddddddddddddddr   Úpublish_compression_childÚ1SessionCompressionMixin.publish_compression_childs  s.   ÿÿ€ ð, 	×&Ñ&÷ (k÷ (kó (kð
 muö	vr   c                óX   € V ^8„  d   QhRRRRRRRRRRR	R
RRRRRRRRRRRRRRRRRRRR/# rÎ   r   )r   s   "r   r   r_   �  sÎ   € ÷ RJñ RJØ.1ðRJØEHðRJØRUðRJà*ðRJà3=ðRJàTiðRJð &ðRJð 4>ðRJð U_ðRJð &0ð	RJð TXð	RJð
 $(ðRJð
 EJðRJð %ðRJð ANðRJð Z^ñRJr   c               óL  € ^ RI Hp V'       d7   V'       d/   VP                  R\        P                  ! 4       V,           W+34       VP                  \        V34      P                  4       pV'       dP   VeA   V'       d9   VR,          V8w  g+   \        VR,          4      \        P                  ! 4       8:  d   V! RV 24      hVP                  RV34      P                  4       pVf   \        RV 24      hVR	,          e:   \        VR
,          4      '       g   \        RV 24      hVP                  RV34       V'       g   \        R4      hV P                  VVW#WFWxWšR7
       V P                  WV4       V P                  WV4      w  ppVe�   VRJpT P                  TRV'       d   RMR R2V\        V4      .V'       d   \        V4      .M. O4      w  ppV'       d0   V P                  VVVR7       V\        V4      ,          pVV,          pVP                  RVVV34       VP                  R\        P                  ! 4       V34      pVP                   ^8w  d   \        RV 24      h\#        W4       ^ RIHp V! WV4       VR,          '       d   V P)                  W4       R# R# )z°:meth:`publish_compression_child` on the caller's write transaction (never commits). The
owner and the worker/canonical-mutation verbs share this one body so they cannot drift.)ÚCompressionSessionBusyErrorúOUPDATE compression_locks SET expires_at = ? WHERE session_id = ? AND holder = ?Nr+   r-   z+Compression lease lost before publication: aP  SELECT ended_at, end_reason, cwd, git_branch, git_repo_root,
                      user_id, session_key, chat_id, chat_type,
                      thread_id, display_name, origin_json, profile_name, tool_names,
                      archived, auto_archived, pinned, model_config, created_source
               FROM sessions WHERE id = ?zCompression parent not found: rb   rc   z"Compression parent already ended: zCUPDATE sessions SET ended_at = NULL, end_reason = NULL WHERE id = ?z+Compression child handoff must not be empty)rN   r¼   r½   r¾   rš   r¿   r£   r¦   zRSELECT id, tool_calls FROM messages WHERE session_id = ? AND active = 1 AND id > ?z AND id <= ?re   z ORDER BY id)r9   zGUPDATE sessions SET message_count = ?, tool_call_count = ? WHERE id = ?z^UPDATE sessions SET ended_at = ?, end_reason = 'compression' WHERE id = ? AND ended_at IS NULLz/Compression parent changed during publication: )Úadvance_local_targetr¯   )Úhermes_state_errorsrÛ   r/   r�   rŽ   r0   r$   ÚRuntimeErrorr   rÄ   Ú_carry_parent_timestampsÚ_insert_message_rowsÚ_tail_rows_after_watermarkrv   Ú_clone_message_rowsr…   r�   rV   Úhermes_state_local_lineagerÝ   Ú _unarchive_auto_archived_lineage)rk   r1   rN   r¼   r½   rÏ   r¾   rš   r¿   r£   r¦   rÆ   rÇ   rÈ   rÉ   rË   rÌ   rÛ   r�   rU   Útotal_messagesÚtotal_tool_callsÚboundedÚtail_idsÚtail_tool_callsr’   rÝ   s   &&$$$$$$$$$$$$$$$          r   rÓ   Ú:SessionCompressionMixin._publish_compression_child_on_conn�  s¿  € õ 	Dß ×%<Ø�L‰LØaÜ—’“Ð0Õ0Ð2CÐ]ô_ð —<‘<¤Ð0AÐ/CÓD×MÑMÓOˆß$ØÒ×$;Ø˜Õ!Ð%<Ô<Ü�X˜lÕ+Ó,´·	²	³Ô;á-Ø=Ð>OÐ=PÐQóSð Sà—‘ð-ð
 Ð ó
÷ ‰(‹*ð 	ð Š>ÜÐ!?Ð@QÐ?RÐSÓTÐTØ�*ÕÒ)ô
 +¨6°,Õ+?×@Ò@Ü"Ð%GÐHYÐGZÐ#[Ó\Ð\Ø�L‰LØUØ"Ð$ô&÷ ÜÐLÓMÐMØ×'Ñ'Ø�&Ð,=Ø°\Øð 	(ô 	0ð 	×%Ñ% d¸xÔHØ+/×+DÑ+DÀTÐ]eÓ+fÑ(ˆÐ(ØÒ ð (¨tÐ3ˆGØ(,×(GÑ(GØð Aç%,‘>°"Ð5°\ðCð #¤C¨	£NÐc×RY´sÐ;LÓ7MÑ6NÐ_aÐcó	)eÑ%ˆH�o÷
 Ø×(Ñ(¨¨xÐDTÐ(ÔUØ¤# h£-Õ/�Ø  OÕ3Ð Ø�‰ØUØÐ-Ð/?Ð@ô	Bð —,‘,ð0Ü26·)²)³+Ð?PÐ1QóSˆð ×Ñ˜qÔ ÜÐ!PÐQbÐPcÐdÓeÐeô 	$ DÔ;ÝCÙ˜TÐ6FÔGØ�*×Ôð ×1Ñ1°$ÖIñ r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úopr(   r9   Úsqlr   rK   r   )r   s   "r   r   r_   ä  s.   € ÷ Eñ E Cð E°Sð E¸sð EÈtñ Er   c                óž   €  V P                  W44       R#   \        P                   d#   p\        P	                  RYT4        Rp?R# Rp?ii ; i)z=``_write_sql`` that logs (never raises) on ``sqlite3.Error``.z%s(%s) failed: %sN)Ú
_write_sqlÚsqlite3ÚErrorrp   rq   )rk   rí   r9   rî   ÚparamsÚexcs   &&&&& r   Ú_write_sql_loggedÚ)SessionCompressionMixin._write_sql_loggedä  s>   € ð	EØ�O‰O˜CÖ(øÜ�}‰}ô 	EÜ�N‰NÐ.°À×DÒDûð	Eús   ‚ •AªAÁAc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r9   r(   r!   r$   r"   r^   r   rK   r   )r   s   "r   r   r_   ë  s2   € ÷ Añ AØðAØ/4ðAØ=JðAØVZñAr   c           	     óF   € V'       g   R# V P                  RVRW"W134       R# )z»Persist the active compression-failure cooldown. Merge-max with any longer live deadline so a
later shorter write can't reopen the thrash window; error always takes the latest diagnostic.NÚ#record_compression_failure_cooldownzüUPDATE sessions SET compression_failure_cooldown_until = CASE WHEN compression_failure_cooldown_until IS NOT NULL  AND compression_failure_cooldown_until > ? THEN compression_failure_cooldown_until ELSE ? END, compression_failure_error = ? WHERE id = ?©rõ   )rk   r9   r!   r"   s   &&&&r   rù   Ú;SessionCompressionMixin.record_compression_failure_cooldownë  s.   € ÷ ÙØ×ÑØ1°:ðmð ¨UÐ?ö	Ar   c               ó    € V ^8„  d   QhRRRR/# )r   r9   r(   r   r‚   r   )r   s   "r   r   r_   ú  s   € ÷ lñ l¸3ð lÐC[ñ lr   c                ó*  € \         P                   ! 4       pV'       d   V P                  \        V34      MRpVe#   V^ ,          e   \        V^ ,          4      V8:  d   R# R\        V^ ,          4      R\        V^ ,          4      V,
          RV^,          /# )zDReturn the active (unexpired) compression-failure cooldown, or None.Nr!   Úremaining_secondsr"   )r�   Ú	_read_oneÚ_COOLDOWN_ROW_SQLr$   )rk   r9   r,   r4   s   &&  r   Ú get_compression_failure_cooldownÚ8SessionCompressionMixin.get_compression_failure_cooldownú  sw   € ä�iŠi‹kˆßBLˆd�n‰nÔ.°°Ô>ÐRVˆØŠ;˜#˜a�&š.¬E°#°aµ&«M¸SÔ,@ÙØ ¤%¨¨A­£-Ð1DÄeÈCÐPQÍFÃmÐVYÕFYÐ[bÐdgÐhiÕdjÐkÐkr   c               ó    € V ^8„  d   QhRRRR/# )r   r9   r(   r   r   r   )r   s   "r   r   r_     s   € ÷ hñ h¸sð hÀ~ñ hr   c                óœ   € V'       d   V P                  \        V34      MRpVf   \        RRR4      # \        RV^ ,          V^,          4      # )z�Exact stored cooldown columns, no expiry filtering, so compression cancellation
can roll back an expired, partially-null, or absent row exactly.NFT)rÿ   r   r%   ©rk   r9   r4   s   && r   Ú$get_compression_failure_cooldown_rowÚ<SessionCompressionMixin.get_compression_failure_cooldown_row  sN   € ÷ CMˆd�n‰nÔ.°°Ô>ÐRVˆØ36²;Œ}˜U D¨$Ó/ÐgÄMÐRVÐX[Ð\]ÕX^Ð`cÐdeÕ`fÓDgÐgr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9   r(   Úsnapshotr   r   rK   r   )r   s   "r   r   r_     s(   € ÷ pñ pÀ3ð pÐR`ð pÐeiñ pr   c                ó$  aaa€ VP                  RR4      '       g5   V P                  S4      P                  RR4      '       d   \        R4      hR# VP                  R4      oVP                  R4      oVVV3R lpV P                  V4      '       g   \        P                  RS4       R# V P                  S4      p\        R	SS4      pWE8w  dD   VP                  RR4      '       g   \        P                  R
S4       R# \        RV: RV: 24      hR# )u�  Restore and verify an exact cooldown-row snapshot. Unlike record/clear this
rollback API propagates write and verification failures: cancellation must not be
reported mutation-free when compensation failed. The tolerated exception is a
session row that vanished mid-attempt â€” before or after the compensating write â€”
since its cooldown died with it and there is nothing left to restore (#106271).r    FzBcannot restore absent compression cooldown row: session now existsNr!   r"   c                óL   <€ V P                  R SSS34      pVP                  ^8H  # )zfUPDATE sessions SET compression_failure_cooldown_until = ?, compression_failure_error = ? WHERE id = ?)r/   r�   )r1   ÚcursorÚdeadliner"   r9   s   & €€€r   rl   ÚMSessionCompressionMixin.restore_compression_failure_cooldown_row.<locals>._do  s3   ø€ Ø—\‘\ð=Ø?GÈÐPZÐ>[ó]ˆFð —?‘? aÑ'Ð'r   z1compression cooldown rollback session missing: %sTz?compression cooldown rollback session missing after restore: %sz<compression cooldown rollback verification failed: expected=z	, actual=)Úgetr  rß   ro   rp   rq   r%   )rk   r9   r	  rl   ÚactualÚexpectedr  r"   s   &f&   @@r   Ú(restore_compression_failure_cooldown_rowÚ@SessionCompressionMixin.restore_compression_failure_cooldown_row  sþ   ú€ ð �|‰|Ð,¨e×4Ò4Ø×8Ñ8¸ÓD×HÑHÐIYÐ[`×aÒaÜ"Ð#gÓhÐhÙØ—<‘<Ð 0Ó1ˆØ—‘˜WÓ%ˆ÷	(ð
 ×"Ñ" 3×'Ò'Ü�N‰NÐNÐPZÔ[ÙØ×:Ñ:¸:ÓFˆÜ   x°Ó7ˆØÔØ—:‘:Ð.°×6Ò6Ü—‘Ð`ÐblÔmÙÜØNÈxÉlÐZcÐdjÑcmÐnópð pñ	 r   c               ó    € V ^8„  d   QhRRRR/# rJ   r   )r   s   "r   r   r_   %  s   € ÷ Lñ L¸Sð LÀTñ Lr   c                óD   € V'       g   R# V P                  RVRV34       R# )z?Clear any persisted compression-failure cooldown for a session.NÚ"clear_compression_failure_cooldownzlUPDATE sessions SET compression_failure_cooldown_until = NULL, compression_failure_error = NULL WHERE id = ?rú   ©rk   r9   s   &&r   r  Ú:SessionCompressionMixin.clear_compression_failure_cooldown%  s&   € çÙØ×ÑØ0°*ð<Ø>H¸]ö	Lr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   Úcolumnr(   r9   ÚcastÚtypeÚzeror   r   r   )r   s   "r   r   r_   .  s1   € ÷ ñ ¨3ð ¸Cð Àtð ÐSVð Ð[^ñ r   c                óÈ   € V'       d   V P                  RV R2V34      MRp Vf   V# \        YC! V^ ,          ;'       g    T4      4      #   \        \        3 d    Tu # i ; i)z~Read one numeric ``sessions`` column clamped at ``zero``; a missing session,
NULL, or unparsable value also reads as ``zero``.zSELECT z FROM sessions WHERE id = ?N)rÿ   ÚmaxÚ	TypeErrorÚ
ValueError)rk   r  r9   r  r  r4   s   &&&&& r   Ú_read_session_numberÚ,SessionCompressionMixin._read_session_number.  sj   € ÷ _iˆd�n‰n˜w v hÐ.IÐJÈZÈMÔZÐnrˆð	Øš;�4ÐK¬C°°d¸3¸q½6¿>¸>ÀTÓ6JÓ,KÐKøÜœ:Ð&ô 	ØŠKð	ús   £A ©A Á 
A ÁA!Á A!c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r  r(   r9   rÀ   r   r   rK   r   )r   s   "r   r   r_   7  s/   € ÷ _ñ _¨Cð _¸Sð _Èð _ÐQUñ _r   c                	ó4   € V P                  R V R2W234       R# )zUPDATE sessions SET z = ? WHERE id = ?N)rð   )rk   r  r9   rÀ   s   &&&&r   Ú_write_session_columnÚ-SessionCompressionMixin._write_session_column7  s   € Ø�‰Ð.¨v¨hÐ6GÐHÈ5ÐJ]Ö^r   c               ó    € V ^8„  d   QhRRRR/# ©r   r9   r(   r   rv   r   )r   s   "r   r   r_   :  ó   € ÷ \ñ \¸#ð \À#ñ \r   c                ó2   € V P                  RV\        ^ 4      # )z3Return the persisted deterministic-fallback streak.Úcompression_fallback_streak©r"  rv   r  s   &&r   Úget_compression_fallback_streakÚ7SessionCompressionMixin.get_compression_fallback_streak:  ó   € à×(Ñ(Ð)FÈ
ÔTWÐYZÓ[Ð[r   c               ó$   € V ^8„  d   QhRRRRRR/# ©r   r9   r(   Ústreakrv   r   rK   r   )r   s   "r   r   r_   >  ó&   € ÷ gñ g¸#ð gÀsð gÈtñ gr   c           
     óf   € V'       d)   V P                  RV\        ^ \        V4      4      4       R# R# )z:Persist the deterministic-fallback streak for one session.r,  N©r&  r  rv   ©rk   r9   r3  s   &&&r   Úset_compression_fallback_streakÚ7SessionCompressionMixin.set_compression_fallback_streak>  ó-   € çØ×&Ñ&Ð'DÀjÔRUÐVWÔY\Ð]cÓYdÓReÖfñ r   c               ó    € V ^8„  d   QhRRRR/# r)  r   )r   s   "r   r   r_   C  s   € ÷ ^ñ ^¸Cð ^ÀCñ ^r   c                ó2   € V P                  RV\        ^ 4      # )uÔ   Persisted ineffective-compaction strike count â€” the durable half of the built-in
compressor's anti-thrash guard, so a fresh compressor bound to a resumed session
inherits an armed/tripped guard across restarts.Úcompression_ineffective_countr-  r  s   &&r   Ú!get_compression_ineffective_countÚ9SessionCompressionMixin.get_compression_ineffective_countC  s   € ð ×(Ñ(Ð)HÈ*ÔVYÐ[\Ó]Ð]r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9   r(   Úcountrv   r   rK   r   )r   s   "r   r   r_   I  s'   € ÷ hñ h¸Cð hÈð hÐPTñ hr   c           
     óf   € V'       d)   V P                  RV\        ^ \        V4      4      4       R# R# )z@Persist the ineffective-compaction strike count for one session.r=  Nr6  )rk   r9   rA  s   &&&r   Ú!set_compression_ineffective_countÚ9SessionCompressionMixin.set_compression_ineffective_countI  s-   € çØ×&Ñ&Ð'FÈ
ÔTWÐXYÔ[^Ð_dÓ[eÓTfÖgñ r   c               ó    € V ^8„  d   QhRRRR/# )r   r9   r(   r   r$   r   )r   s   "r   r   r_   N  s   € ÷ bñ b¸Cð bÀEñ br   c                ó2   € V P                  RV\        R4      # )a‘  Persisted anti-thrash recovery deadline (epoch; ``0.0`` = not armed). Durable
because the gateway rebuilds the compressor every turn / cache eviction.

The deadline is the durable half of the 14694 recovery clock: the gateway rebuilds the compressor on
every turn / cache eviction, so a process-local deadline restarted the wait on each rebuild and a
tripped session never earned its probe (#100185).
Úcompression_recovery_deadlineç        )r"  r$   r  s   &&r   Ú!get_compression_recovery_deadlineÚ9SessionCompressionMixin.get_compression_recovery_deadlineN  s   € ð ×(Ñ(Ð)HÈ*ÔV[Ð]`ÓaÐar   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9   r(   r  r$   r   rK   r   )r   s   "r   r   r_   X  s'   € ÷ dñ d¸Cð dÈ5ð dÐUYñ dr   c                óÄ   € V'       g   R#  \        R\        T;'       g    R4      4      pT P	                  RY;'       g    R4       R#   \        \        3 d    Rp L3i ; i)zGPersist the anti-thrash recovery deadline; ``0`` / ``None`` disarms it.NrH  rG  )r  r$   r   r!  r&  )rk   r9   r  Ú
normalizeds   &&& r   Ú!set_compression_recovery_deadlineÚ9SessionCompressionMixin.set_compression_recovery_deadlineX  s[   € çÙð	Ü˜S¤%¨¯¨°CÓ"8Ó9ˆJð 	×"Ñ"Ð#BÀJ×PbÐPbÐ^bÖcøô œ:Ð&ô 	ØŠJð	ús   ŒA	  A	 Á	AÁAc               ó    € V ^8„  d   QhRRRR/# r)  r   )r   s   "r   r   r_   b  r*  r   c                ó2   € V P                  RV\        ^ 4      # )z?Return the persisted sustained-overload abort streak (#123167).Úcompression_overload_streakr-  r  s   &&r   Úget_compression_overload_streakÚ7SessionCompressionMixin.get_compression_overload_streakb  r0  r   c               ó$   € V ^8„  d   QhRRRRRR/# r2  r   )r   s   "r   r   r_   f  r4  r   c           
     óf   € V'       d)   V P                  RV\        ^ \        V4      4      4       R# R# )z<Persist the sustained-overload abort streak for one session.rR  Nr6  r7  s   &&&r   Úset_compression_overload_streakÚ7SessionCompressionMixin.set_compression_overload_streakf  r:  r   c               ó    € V ^8„  d   QhRRRR/# )r   r9   r(   r   rÐ   r   )r   s   "r   r   r_   k  s   € ÷ 
(ñ 
(Àð 
(Èñ 
(r   c                óF   a€ S'       g   R# V3R lpV P                  V4      # )z¤Atomically bump the overload streak and return the new value (None when no row).
One UPDATE ... RETURNING, so concurrent agents on one session cannot lose a strike.Nc                óv   <€ V P                  R S34      P                  4       pVf   R# \        V^ ,          4      # )z„UPDATE sessions SET compression_overload_streak = compression_overload_streak + 1 WHERE id = ? RETURNING compression_overload_streakN)r/   r0   rv   )r1   r4   r9   s   & €r   rl   ÚJSessionCompressionMixin.increment_compression_overload_streak.<locals>._dop  sB   ø€ Ø—,‘,ðFØHRÀ}óVçV^ÑV^ÓV`ð ð š;�4Ð7¬C°°Aµ«KÐ7r   r~   r”   s   &f r   Ú%increment_compression_overload_streakÚ=SessionCompressionMixin.increment_compression_overload_streakk  s#   ø€ ÷ Ùõ	8ð
 ×"Ñ" 3Ó'Ð'r   c               ó(   € V ^8„  d   QhRRRRRRRR/# ©r   r9   r(   r+   Úttl_secondsr$   r   r   r   )r   s   "r   r   r_   w  s*   € ÷ ñ °3ð Àð ÐRWð Ðdhñ r   c                ó   € V'       d	   V'       g   R# \         P                   ! 4       V,           p V P                  RWAV34      ^ 8„  #   \        P                   d"   p\        P                  RY4        Rp?R# Rp?ii ; i)uö  Extend the compression lock lease if ``holder`` still owns it. Ownership is decided by ``holder``
alone, deliberately NOT ``expires_at``: a live owner whose refresher stalled past its TTL must be
able to revive its still-unclaimed row, otherwise it keeps compressing with no lease â€” the window in
which a competing path can fork the lineage. It cannot resurrect a lock someone else took: SQLite
serialises writes, so the reclaim (DELETE-expired + INSERT OR IGNORE) never interleaves with this
UPDATE.FrÜ   z'refresh_compression_lock(%s) failed: %sN)r�   Ú_write_rowcountrñ   rò   rp   rq   )rk   r9   r+   ra  r-   rô   s   &&&&  r   Úrefresh_compression_lockÚ0SessionCompressionMixin.refresh_compression_lockw  so   € ÷ §ÙÜ—Y’Y“[ ;Õ.ˆ
ð	Ø×'Ñ'ØaØ¨Ð0ó2à45ñ6ð 6øô �}‰}ô 	Ü�N‰NÐDÀjÔVÝûð	ús   °A ÁA=ÁA8Á8A=c               ó(   € V ^8„  d   QhRRRRRRRR/# r`  r   )r   s   "r   r   r_   ‰  s*   € ÷ ñ °sð ÀCð ÐV[ð Ðhlñ r   c                ól  aaaa	a
€ ^ RI Ho S'       g   R# \        P                  ! 4       o
S
V,           o	VV	VV
V3R lp V P                  V4      w  rVV'       d   \        P                  RSV4       \        V4      #   \        P                   d#   p\        P                  RST4        Rp?R# Rp?ii ; i)a  Try to atomically acquire the compression lock for ``session_id``. ``False``: another holder owns
a live lock and the caller MUST NOT compress (its rotation would split the lineage). Expired
locks and structured holders whose local ``pid=`` is dead are reclaimed transparently.©Ú(_compression_lock_holder_process_is_deadFc                ó2   <€ \        V R RSSSSVV3R l4      # )Úcompression_locksr9   c                ó.   <€ VS8  ;'       g	    S! V 4      # rœ   r   ©ÚhÚeri  r,   s   &&€€r   rÔ   ÚSSessionCompressionMixin.try_acquire_compression_lock.<locals>._do.<locals>.<lambda>•  s   ø€ ˜Q ™W×SÐSÑ(PÐQRÓ(SÐSr   )r6   )r1   ri  r-   r+   r,   r9   s   &€€€€€r   rl   ÚASessionCompressionMixin.try_acquire_compression_lock.<locals>._do’  s&   ø€ Ü#ØÐ)¨<¸ÀVÈSÐR\ÝSóUð Ur   z;Reclaimed stale compression lock for session=%s (holder=%s)z+try_acquire_compression_lock(%s) failed: %sN)	r   ri  r�   ro   rp   rq   r   rñ   rò   )rk   r9   r+   ra  rl   Úacquiredr3   rô   ri  r-   r,   s   &ff&    @@@r   Útry_acquire_compression_lockÚ4SessionCompressionMixin.try_acquire_compression_lock‰  s“   ü€ õ 	JßÙÜ�iŠi‹kˆØ˜;Õ&ˆ
÷	Uñ 	Uð
		Ø)-×)<Ñ)<¸SÓ)AÑ&ˆHßÜ—‘Ð\Ø)Ð+;ô=ä˜“>Ð!øÜ�}‰}ô 	ä�N‰NÐHÈ*ÐVYÔZÝûð	ús   ¿<A< Á<B3ÂB.Â.B3c               ó$   € V ^8„  d   QhRRRRRR/# ©r   r9   r(   r+   r   rK   r   )r   s   "r   r   r_   ¢  s!   € ÷ "ñ "°3ð "Àð "Èñ "r   c                óD   € V'       g   R# V P                  RVRW34       R# )zKRelease the compression lock iff we own it; idempotent when gone/reclaimed.NÚrelease_compression_lockzADELETE FROM compression_locks WHERE session_id = ? AND holder = ?rú   )rk   r9   r+   s   &&&r   rx  Ú0SessionCompressionMixin.release_compression_lock¢  s$   € çÙØ×ÑØ&¨
ØOØÐ ö	"r   c               ó    € V ^8„  d   QhRRRR/# ©r   r9   r(   r   r   )r   s   "r   r   r_   «  s   € ÷ Oñ OÀð OÈñ Or   c                ó–  a€ V'       g   V# R V3R llpV! V4      pV0pV'       dv   VP                  R4      pV'       d    We9   g   V P                  VRR7      '       d   M<V! V4      pV'       d   VP                  R4      R8w  d   MVP                  V4       TpK}  V'       d%   \        VP                  R4      ;'       g    T4      # T# )	a!  Walk compression parents on ``conn`` to the conversation lease key. Must share
the connection of the lease INSERT/UPDATE/DELETE: a failed lookup must not yield a
child id the write then persists. Markers bind to ``parent_session_id``. Lock
errors propagate so ``_execute_write`` can retry.c               ó   € V ^8„  d   QhRR/# )r   Úsidr(   r   )r   s   "r   r   ÚMSessionCompressionMixin._session_turn_lease_key_on_conn.<locals>.__annotate__²  s   € ÷ 	.ñ 	.�cñ 	.r   c                óp   <€ SP                  R V 34      P                  4       pV'       d   \        V4      # R# )zYSELECT id, parent_session_id, source, model_config, end_reason FROM sessions WHERE id = ?N)r/   r0   Údict)r~  r4   r1   s   & €r   Ú_rowÚESessionCompressionMixin._session_turn_lease_key_on_conn.<locals>._row²  s6   ø€ Ø—,‘,ØkØ�óç ™›
ð ÷ !$”4˜“9Ð-¨Ð-r   rN   T©Úinclude_resetrc   rd   r;   )r  Ú_is_explicit_fork_child_rowr?   r(   )rk   r1   r9   r‚  rB   rD   rT   rU   s   &f&     r   Ú_session_turn_lease_key_on_connÚ7SessionCompressionMixin._session_turn_lease_key_on_conn«  s²   ø€ ÷
 ØÐ÷	.ð 	.ñ �zÓ"ˆØˆ|ˆßØŸ™Ð$7Ó8ˆIß 	Ô 1°T×5UÑ5UÐV]ÐmqÐ5U×5rÒ5rØÙ˜)“_ˆFß˜VŸZ™Z¨Ó5¸ÔFØØ�H‰H�YÔØŠGß7>Œs�7—;‘;˜tÓ$×2Ð2¨
Ó3ÐNÀJÐNr   c               ó    € V ^8„  d   QhRRRR/# r{  r   )r   s   "r   r   r_   Å  s   € ÷ Jñ J°#ð J¸#ñ Jr   c                ó¦   € V'       g   V# V P                  4       ;_uu_ 4       pV P                  W!4      uuRRR4       #   + '       g   i     R# ; i)zšStable serialization key for every compression segment (tests/diagnostics; the
write paths resolve it inside their own txn). Does not swallow lock errors.N)r„   r‡  )rk   r9   r1   s   && r   Ú_session_turn_lease_keyÚ/SessionCompressionMixin._session_turn_lease_keyÅ  s9   € ÷ ØÐØ�^‰^×Ô Ø×7Ñ7¸ÓI÷ ××Óús	   £?¿A	ra  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# ©
r   r9   r(   r+   ra  r$   rZ   r]   r   r   r   )r   s   "r   r   r_   Í  s;   € ÷ Eñ EØðEØ'*ðEØ<AðEØWfðEà	ñEr   c               óì   a aaaaa€ ^ RI Ho S'       d	   S'       g   R# \        P                  ! 4       oS\        R\	        V4      4      ,           oVVVVV V3R lp\        S P                  WTR7      4      # )zÂAtomically acquire the cross-process turn lease for a conversation (keyed by the
lineage root). The walk, the INSERT, and reclaim of expired or dead-local-PID leases
share one write transaction.rh  Fçš™™™™™¹?c                ó    <€ V P                  R S\        ,
          34       SP                  V S4      p\        V RRVSSSVV3R l4      ^ ,          # )z4DELETE FROM session_turn_leases WHERE expires_at < ?Úsession_turn_leasesÚconversation_idc                ó@   <€ \        V4      S8*  ;'       g	    S! V 4      # rœ   r#   rm  s   &&€€r   rÔ   ÚUSessionCompressionMixin.try_acquire_session_turn_lease.<locals>._do.<locals>.<lambda>â  s   ø€ œU 1›X¨™_×[Ð[Ñ0XÐYZÓ0[Ð[r   )r/   Ú_TURN_LEASE_SWEEP_GRACE_Sr‡  r6   )r1   r“  ri  r-   r+   r,   rk   r9   s   & €€€€€€r   rl   ÚCSessionCompressionMixin.try_acquire_session_turn_lease.<locals>._doØ  s`   ø€ ð
 �L‰LÐOØÔ 9Õ9Ð;ô=à"×BÑBÀ4ÈÓTˆOÜ#ØÐ+Ð->ÀÐQWÐY\Ð^hÝ[óð õð r   rn   )r   ri  r�   r  r$   r   ro   )	rk   r9   r+   ra  rZ   rl   ri  r-   r,   s	   fff$$ @@@r   Útry_acquire_session_turn_leaseÚ6SessionCompressionMixin.try_acquire_session_turn_leaseÍ  sW   ý€ õ 	Jß§ÙÜ�iŠi‹kˆØœ3˜s¤E¨+Ó$6Ó7Õ7ˆ
÷	ò 	ô �D×'Ñ'¨Ð'ÓCÓDÐDr   Úwait_secondsg      œ@Úpoll_interval_secondsg      ð?Úon_waitÚwait_notice_interval_secondsg      .@Úshould_abortÚacquire_patience_sg      à?Úon_contendedc               ó8   € V ^8„  d   QhRRRRRRRRRRRRR	RR
R/# )r   r9   r(   r+   ra  r$   rš  r›  r�  rŸ  r   r   r   )r   s   "r   r   r_   æ  s^   € ÷ <Pñ <PØð<PØ'*ð<PØ<Að<Pàð<Pà=Bð<Pð ',ð<Pð \að<Pð
 
ñ<Pr   c          
     ó€  € ^ RI Hp \        P                  ! 4       \	        R\        V4      4      ,           pT	pRpRp\	        R\        V4      4      p Ve    V! 4       '       d   R#   V P                  WW=R7      '       d   R#  T	p\        P                  ! 4       pTT,
          pT^ 8:  d   R# Tf   TpTe6   Te   TR8X  g   TT,
          T8¼  d    T! \	        RTT,
          4      4       Tp\        P                  ! \        \	        R\        T4      4      T4      4       KÐ    \         d    \        P                  RRR7        LÞi ; i  \        P                   d·   pT! T4      R	8w  d   h T
e2    T
! 4        M(  \         d    \        P                  R
RR7        Mi ; i\        T	\	        R\        T4      4      ,           \	        Yœ\        P                  ! 4       ,
          4      4      pT P                  TR4      '       g    Rp?R#  Rp?EK¾  Rp?ii ; i  \         d    \        P                  RRR7        ELRi ; i)aÆ  Wait for a cross-process turn lease without holding a SQLite lock. ``on_wait(elapsed)`` is
best-effort: called when another holder has the lease and about every
``wait_notice_interval_seconds`` after. A busy database is not a holder: the attempt is
retried at once with a longer write patience, and ``on_contended()`` is called instead,
since the busy writer may be the holder's last flush. ``should_abort()`` True (e.g.
``/stop``) returns False at once.)Úclassify_persistence_errorrH  NTFz/session turn lease should_abort callback failed)Úexc_info)ra  rZ   Úlockedz/session turn lease on_contended callback failedz*session turn lease on_wait callback failedg{®Gáz„?)r   r£  r�   Ú	monotonicr  r$   Ú	Exceptionrp   Údebugr˜  rñ   rò   ÚminÚ_sleep_before_write_retryÚsleep)rk   r9   r+   ra  rš  r›  rœ  r�  rž  rŸ  r   r£  r  ÚpatienceÚwait_startedÚlast_notice_atÚnotice_everyrô   r,   Ú	remainings   &&&$$$$$$$$         r   Úacquire_session_turn_leaseÚ2SessionCompressionMixin.acquire_session_turn_leaseæ  s  € õ 	<Ü—>’>Ó#¤c¨#¬u°\Ó/BÓ&CÕCˆØ%ˆØˆØˆÜ˜3¤Ð&BÓ CÓDˆØØÒ'ðcÙ#—~’~Ù$ð &ðØ×6Ñ6Ø°Kð 7÷ Vò VáðVð& *ˆHÜ—.’.Ó"ˆCØ  3�ˆIØ˜AŒ~ÙØÒ#Ø"�ØÒ"ØÒ&¨,¸#Ô*=À#ÈÕBVÐ[gÔAgð^ÙœC  S¨<Õ%7Ó8Ô9ð "%�Ü�JŠJ”sœ3˜t¤UÐ+@Ó%AÓBÀIÓNÖOøôK !ô cÜ—L‘LÐ!RÐ]a�LÖbðcûô —=‘=ô ñ .¨cÓ2°hÔ>ØØÒ+ðgÙ$�øÜ$ô gÜŸ™Ð%VÐae˜ÖfðgúäÐ1´C¸¼UÐCXÓ=YÓ4ZÕZÜ"Ð#5Ä$Ç.Â.ÓBRÕ7RÓSóU�à×5Ñ5°hÀ×DÒDÝ Þûðûô8 !ô ^Ü—L‘LÐ!MÐX\�L×]ð^úsa   ÁD! Á(E	 ÃH Ä!"EÅEÅ	HÅHÅ1E9Å8HÅ9"FÆHÆFÆA$HÈHÈ"H=È<H=c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9   r(   r+   r   r]   r   )r   s   "r   r   r_   $  s!   € ÷ 	.ñ 	.¸ð 	.ÀSð 	.È_ñ 	.r   c           	     ó(  € V'       d	   V'       g   R# V P                  4       ;_uu_ 4       pVP                  RV P                  W14      V34      P                  4       pRRR4       X'       d   \	        V^ ,          4      # R#   + '       g   i     L,; i)zVCommitted ``expires_at`` of ``holder``'s turn lease, or None when it does not hold it.NzSSELECT expires_at FROM session_turn_leases WHERE conversation_id = ? AND holder = ?)r„   r/   r‡  r0   r$   )rk   r9   r+   r1   r4   s   &&&  r   Úsession_turn_lease_expires_atÚ5SessionCompressionMixin.session_turn_lease_expires_at$  sn   € ç§ÙØ�^‰^×Ô Ø—,‘,ØeØ×5Ñ5°dÓGÈÐPó÷ ‰h‹jð ÷ ÷
 !$Œu�S˜•V‹}Ð-¨Ð-÷ ×ús   «2BÂB	c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# rŽ  r   )r   s   "r   r   r_   /  s;   € ÷ Eñ EØðEØ'*ðEØ<AðEØWfðEà	ñEr   c               óÔ   a aaa€ S'       d	   S'       g   R# \         P                   ! 4       \        R\        V4      4      ,           oVVV V3R lp\        S P	                  WTR7      4      # )z­Extend a turn lease only while ``holder`` still owns it. ``expires_at`` is stamped before
the write-lock wait, so a caller timestamp taken before this call never exceeds it.Fr�  c                ól   <€ SP                  V S4      pV P                  R SVS34      P                  ^ 8„  # )zVUPDATE session_turn_leases SET expires_at = ? WHERE conversation_id = ? AND holder = ?)r‡  r/   r�   )r1   r“  r-   r+   rk   r9   s   & €€€€r   rl   Ú?SessionCompressionMixin.refresh_session_turn_lease.<locals>._do7  sD   ø€ Ø"×BÑBÀ4ÈÓTˆOØ—<‘<ð;Ø=GÈÐZ`Ð<aó÷ ‰h˜ñð r   rn   )r�   r  r$   r   ro   )rk   r9   r+   ra  rZ   rl   r-   s   fff$$ @r   Úrefresh_session_turn_leaseÚ2SessionCompressionMixin.refresh_session_turn_lease/  sN   û€ ÷
 §ÙÜ—Y’Y“[¤3 s¬E°+Ó,>Ó#?Õ?ˆ
÷	ð 	ô �D×'Ñ'¨Ð'ÓCÓDÐDr   c               ó$   € V ^8„  d   QhRRRRRR/# rv  r   )r   s   "r   r   r_   ?  s!   € ÷ 	!ñ 	!°Sð 	!À#ð 	!È$ñ 	!r   c                ób   a aa€ S'       d	   S'       g   R# VV V3R lpS P                  V4       R# )z>Release a turn lease iff ``holder`` still owns it; idempotent.Nc                óT   <€ SP                  V S4      pV P                  R VS34       R# )zHDELETE FROM session_turn_leases WHERE conversation_id = ? AND holder = ?N)r‡  r/   )r1   r“  r+   rk   r9   s   & €€€r   rl   Ú?SessionCompressionMixin.release_session_turn_lease.<locals>._doC  s,   ø€ Ø"×BÑBÀ4ÈÓTˆOØ�L‰LØZØ  &Ð)ö+r   r~   )rk   r9   r+   rl   s   fff r   Úrelease_session_turn_leaseÚ2SessionCompressionMixin.release_session_turn_lease?  s    ú€ ç§Ù÷	+ð
 	×Ñ˜CÖ r   c               ó    € V ^8„  d   QhRRRR/# ©r   r9   r(   r   r^   r   )r   s   "r   r   r_   J  s   € ÷ /ñ /°cð /¸mñ /r   c                ó‚   € V'       g   R# V P                  RV\        P                  ! 4       34      pVf   R# V^ ,          # )zJCurrent (non-expired) holder for ``session_id``, or None. Diagnostic only.NzMSELECT holder FROM compression_locks WHERE session_id = ? AND expires_at >= ?)rÿ   r�   r  s   && r   Úget_compression_lock_holderÚ3SessionCompressionMixin.get_compression_lock_holderJ  s?   € çÙØ�n‰nØ[Ð^hÔjn×jsÒjsÓjuÐ]vóxˆà’{ˆtÐ.¨¨A­Ð.r   c               ó   € V ^8„  d   QhRR/# ru   r   )r   s   "r   r   r_   R  s   € ÷ ñ ¸ñ r   c                óœ   € \         P                   ! 4       R,
          pV P                  R\         P                   ! 4       V34      ;'       g    ^ # )zÖMark orphaned compression continuations (parent ended by compression; child has
messages, no end_reason/ended_at, api_call_count=0, older than 7 days) as
``orphaned_compression``. Non-destructive.

Fix for #20001.
i€:	 a  
                UPDATE sessions
                SET ended_at = ?,
                    end_reason = 'orphaned_compression'
                WHERE api_call_count = 0
                  AND end_reason IS NULL
                  AND ended_at IS NULL
                  AND started_at < ?
                  AND parent_session_id IS NOT NULL
                  AND EXISTS (
                      SELECT 1 FROM sessions p
                      WHERE p.id = sessions.parent_session_id
                        AND p.end_reason = 'compression'
                        AND p.ended_at IS NOT NULL
                  )
                  AND EXISTS (
                      SELECT 1 FROM messages m
                      WHERE m.session_id = sessions.id
                  )
                )r�   rc  )rk   Úcutoffs   & r   Ú&finalize_orphaned_compression_sessionsÚ>SessionCompressionMixin.finalize_orphaned_compression_sessionsR  sK   € ô —’“˜vÕ%ˆØ×#Ñ#ðô( —’“˜fÐ%ó+
÷ ð ð, ð-	r   c               ó    € V ^8„  d   QhRRRR/# r8   r   )r   s   "r   r   r_   r  s   € ÷ 9ñ 9°ð 9¸	ñ 9r   c                ó,   a € R V 3R llp\        W4      # )an  Walk the compression-continuation chain forward: root-first through the tip (``[session_id]``
when no continuation); ``get_compression_tip`` is the last element. A continuation is a child of
a session with ``end_reason='compression'``. The old ``child.started_at >= parent.ended_at`` test
was too brittle (gateway + compression races insert the real continuation before ``ended_at`` is
written, while a stale websocket later creates a sibling that passes it). Instead exclude
branch/delegate/tool children and prefer children that continue the chain or are still live over
stale closed siblings such as ``ws_orphan_reap``.c               ó   € V ^8„  d   QhRR/# )r   rB   r(   r   )r   s   "r   r   ÚCSessionCompressionMixin.get_compression_chain.<locals>.__annotate__z  s   € ÷ 	Lñ 	L˜#ñ 	Lr   c                ó¼   <€ SP                  4       ;_uu_ 4       pVP                  \        V 34      P                  4       uuR R R 4       #   + '       g   i     R # ; irœ   )r„   r/   rR   r0   )rB   r1   rk   s   & €r   rA   Ú;SessionCompressionMixin.get_compression_chain.<locals>.stepz  s:   ø€ Ø—‘×!Ô! TØ—|‘|¤O°g°ZÓ@×IÑIÓK÷ "×!×!Ó!ús   š%A
Á
A	©rG   )rk   r9   rA   s   f& r   Úget_compression_chainÚ-SessionCompressionMixin.get_compression_chainr  s   ø€ ÷	Lð 	Lô ' zÓ8Ð8r   c               ó    € V ^8„  d   QhRRRR/# rÄ  r   )r   s   "r   r   r_     s   € ÷ 2ñ 2¨cð 2°mñ 2r   c                óJ   € V P                  V4      pV'       d
   VR,          # T# )zpLive tip of a compression chain (``get_compression_chain`` semantics); the input
id when no continuation exists.éÿÿÿÿ)rÔ  )rk   r9   rC   s   && r   Úget_compression_tipÚ+SessionCompressionMixin.get_compression_tip  s%   € ð ×*Ñ*¨:Ó6ˆß!ˆu�R�yÐ1 zÐ1r   c               ó    € V ^8„  d   QhRRRR/# r{  r   )r   s   "r   r   r_   …  s   € ÷ }ñ }°Cð }¸Cñ }r   c                ó2   a€ \        VV3R l4      R,          # )z‘``get_compression_tip`` read on a writer's own connection: inside its transaction no rotation
can publish between finding the tip and writing it.c                óN   <€ SP                  \        V 34      P                  4       # rœ   )r/   rR   r0   )rB   r1   s   &€r   rÔ   Ú=SessionCompressionMixin._compression_tip_on.<locals>.<lambda>ˆ  s   ø€ À4Ç<Á<ÔP_ÐbiÐakÓCl×CuÑCuÔCwr   rØ  rÓ  )rk   r1   r9   s   &f&r   Ú_compression_tip_onÚ+SessionCompressionMixin._compression_tip_on…  s   ø€ ô ' zÔ3wÓxÐy{Õ|Ð|r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r   r   )r   s   "r   r   r_   Š  s   € ÷ Jñ J¨~ð JÀ$ñ Jr   c                	óÚ   € VP                  R 4      pV'       d   V P                  VRR7      '       d   R# V P                  V4      p\        T;'       d    VP                  R4      R8H  4      # )rN   Tr„  Frc   rd   )r  r†  Úget_sessionr   )rk   r   rT   rU   s   &&  r   Ú_is_compression_child_rowÚ1SessionCompressionMixin._is_compression_child_rowŠ  s^   € Ø—I‘IÐ1Ó2ˆ	ç˜D×<Ñ<¸UÐRVÐ<×WÒWÙØ×!Ñ! )Ó,ˆÜ�F×HÐH˜vŸz™z¨,Ó7¸=ÑHÓIÐIr   c               ó    € V ^8„  d   QhRRRR/# r8   r   )r   s   "r   r   r_   ’  s   € ÷ Bñ B°#ð B¸)ñ Br   c                ó¾  a € S P                  V4      pV'       d   S P                  V4      '       d   V'       d   V.# . # TpVR,          0pS P                  V4      '       dL   S P                  VR,          4      pV'       d   VR,          V9   d   MTpVP                  VR,          4       Kb  VR,          .pVR,          0pTpVP	                  R4      R8X  d|   S P                  RVR,          34      p	\        V 3R lV	 4       R4      p
V
'       d   V
R,          V9   d   M4VP                  V
R,          4       VP                  V
R,          4       T
pK‘  W9   d   V# V.# )z@Return compression ancestors through tip in chronological order.r;   rN   rc   rd   zŒ
                SELECT * FROM sessions
                WHERE parent_session_id = ?
                ORDER BY started_at ASC
                c              3  ó~   <"  € T F2  pSP                  \        V4      4      '       g   K%  \        V4      x € K4  	  R # 5irœ   )rä  r�  )r�   r4   rk   s   & €r   rŸ   ÚBSessionCompressionMixin.get_compression_lineage.<locals>.<genexpr>©  s-   øé € Ðf±D¨S¸D×<ZÑ<ZÔ[_Ð`cÓ[d×<eœyœt CŸy˜y³Dùs   ƒ"=ª=N)rã  r†  rä  r?   r  Ú	_read_allÚnextr@   )rk   r9   ÚsessionÚrootÚ	ancestorsrU   ÚlineagerD   rB   r‡   Ú
next_childs   f&         r   Úget_compression_lineageÚ/SessionCompressionMixin.get_compression_lineage’  s=  ø€ à×"Ñ" :Ó.ˆß˜$×:Ñ:¸7×CÒCß#*�J�<Ð2°Ð2ØˆØ˜$•Z�Lˆ	Ø×,Ñ,¨T×2Ò2Ø×%Ñ% dÐ+>Õ&?Ó@ˆFß˜V D�\¨YÔ6ØØˆDØ�M‰M˜$˜t�*Ö%Ø˜•:�,ˆØ�T•
ˆ|ˆØˆØ�k‰k˜,Ó'¨=Ô8Ø—>‘>ðð ˜d•mÐ%ó'ˆDô Ôf±DÓfÐhlÓmˆJß ¨DÕ!1°TÔ!9ØØ�N‰N˜: dÕ+Ô,Ø�H‰H�Z Õ%Ô&Ø ŠGà$Ô/ˆwÐA°j°\ÐAr   r   rœ   )rÊ   )/Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rr   r   rˆ   r•   rÄ   r×   rÓ   rõ   rù   r  r  r  r  r"  r&  r.  r8  r>  rC  rI  rN  rS  rW  r]  rd  rs  rx  r‡  r‹  r˜  r±  rµ  r»  rÁ  rÆ  rË  rÔ  rÙ  rß  rä  rñ  Ú__static_attributes__r   r   r   rY   rY   ³   s�  † ÙOð)ØQU÷)õV(õKõ87.õr-
ð^và<@ðvàhlðvð %)ðvð =Aðvð ^bðvð /3ð	vð W[ð	vð
 ',ðvð
 INðvð $(ðvð MQ÷vð:RJà@DðRJàlpðRJð )-ðRJð AEðRJð bfðRJð 37ð	RJð [_ð	RJð
 +0ðRJð
 MRðRJð (,ðRJð QU÷RJõhE÷Aõlõhõpõ:Lõõ_õ\õgõ
^õhõ
bõdõ\õgõ

(÷÷$õ2"õOõ4JðEØDIðEØim÷Eð2<PØDIð<Pà$ð<PàEHð<PàRVð<Pð /3ð<Pð BFð<Pð dgð<Pð ÷	<Põ|	.ðEØDIðEØim÷Eõ 	!õ/õõ@9õ2õ}õ
J÷Bñ Br   rY   )Úonboarding_run>   Nre   ÚlocalÚunknown)+r÷  Ú
__future__r   r¹   Úloggingrñ   r�   Útypingr   r   r   r   r   Úhermes_state_commonr   r	   rŽ   r
   r   r   r   r   r   r   Ú	getLoggerrp   r   r   rR   r–  r%   r6   r>   rµ   rG   Ú	frozensetrP   Ú_UNSET_CREATED_SQLrO   rQ   rV   rz   rY   r   r   r   Ú<module>r     s„  ðñCõ
 #ã Û Û Û ß 3Õ 3÷÷ õ ð 
×	Ò	˜>Ó	*€ð fð ðñ -Ð-AÐCUÓVÐWð XÙ,Ð-AÐCUÓVÐWð X Ø 0× 7Ò 7¸'Ô BÐCð Dñ 0°Ó8Ð9ð :ð!€ð0 $Ð õmõ
Mð( €
ð
 #6Ð õñ, #Ò#AÓBÐ ØFÐ ØXÐ ð/ð 2D×1JÑ1JÐOaÐ1JÓ1bõcðfõ
Ð õDðL!1à1C×1JÑ1JÐOfÐ1JÓ1gÐ0hð iØ!×(Ñ(Ð-CÐ(ÓDÐEð FÙ˜X {Ó3Ð 4ð	8Ð ÷}Bó }Br   