Ë
    uPêjëQ  ã                  ó„  — U d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlmZmZmZmZmZ ddlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' ddl(m)Z) ddl*m+Z+ dZ,de-d<   dZ.de-d<   ddl/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7 dd„Z8 e	dd¬«       G d„ d«      «       Z9 G d„ d«      Z:y)aò  
Main adaptive router strategy. See README.md for design overview.

One AdaptiveRouter instance per router_name. Holds in-memory caches:
- _cells:           Beta(alpha, beta) bandit posteriors per (request_type, model)
- _session_states:  (session_key, model) -> SessionState for incremental signal updates

Owns the AdaptiveRouterUpdateQueue used by the proxy's flusher to persist
state and session snapshots back to Postgres.

Routing is stateless per-turn (Thompson sample fresh on every call).
é    )ÚannotationsN)ÚOrderedDict)ÚasdictÚ	dataclass)ÚAnyÚFinalÚcast)Úverbose_router_logger)Úget_last_user_message)Ú
BanditCellÚapply_deltaÚinitial_cellÚ	pick_best)Úclassify_prompt)Ú ADAPTIVE_ROUTER_CHOSEN_MODEL_KEYÚMIN_QUALITY_TIER_HEADERÚMIN_QUALITY_TIER_METADATA_KEYÚMIN_TURNS_FOR_CLEAN_CREDITÚOWNER_CACHE_TTL_SECONDS)ÚSessionStateÚSignalDeltaÚTurnÚadvance_session_stateÚapply_signal_deltaÚdetect_response_signalsÚdetect_user_feedbackÚmerge_signal_deltas)ÚAdaptiveRouterUpdateQueue)ÚStandardLoggingRoutingDecisioni   z
Final[int]Ú_SESSION_STATE_SWEEP_THRESHOLDÚ_FEEDBACK_CONTEXT_MAX_ENTRIES)ÚAdaptiveRouterStateRepository)ÚAllMessageValues)ÚAdaptiveRouterConfigÚAdaptiveRouterPreferencesÚPreRoutingHookResponseÚRequestTypec                 ó   — t        dg ¬«      S )zGTier-2 prior with no declared strengths; used when a model omits prefs.é   )Úquality_tierÚ	strengths)r%   © ó    ú|/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/router_strategy/adaptive_router/adaptive_router.pyÚ_default_prefsr/   E   s   € ä$°!¸rÔBÐBr-   T)ÚfrozenÚslotsc                  óT   — e Zd ZU ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   y)Ú_FeedbackContextÚstrÚ
model_namer'   Úrequest_typez
str | NoneÚuser_contentÚassistant_contentÚintÚ
turn_countÚboolÚclean_credit_awardedÚfloatÚ
expires_atN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r,   r-   r.   r3   r3   J   s*   … àƒOØÓØÓØ!Ó!ØƒOØÓØÔr-   r3   c                  ó  — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Z	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Z	 d	 	 	 	 	 dd„Zdd„Z	e
	 	 	 	 dd	„«       Zdd
„Z	 	 	 	 	 	 	 	 dd„Zdd„Z	 	 	 	 	 	 	 	 	 	 dd„Ze
dd„«       Ze
dd„«       Zy)ÚAdaptiveRouterzHOne instance per router_name. Holds in-memory caches + the update queue.c                ó:  — || _         || _        || _        || _        t	        «       | _        i | _        i | _        t        «       | _	        i | _
        d| _        d| _        d| _        d| _        d| _        t!        j"                  «       | _        | j'                  «        y )Nr   F)Úrouter_nameÚconfigÚmodel_to_prefsÚmodel_to_costr   ÚqueueÚ_cellsÚ_session_statesr   Ú_feedback_contextsÚ_session_states_expiryÚ_feedback_attributed_totalÚ_feedback_without_context_totalÚ_cross_model_feedback_totalÚ_response_signal_updates_totalÚ_state_loadedÚasyncioÚLockÚ_lockÚ_init_cold_start_cells)ÚselfrF   rG   rH   rI   s        r.   Ú__init__zAdaptiveRouter.__init__X   s‘   € ð 'ˆÔØˆŒØ,ˆÔØ*ˆÔÜ.Ó0ˆŒ
àACˆŒØDFˆÔÜFQÃmˆÔØDFˆÔ#Ø/0ˆÔ'Ø45ˆÔ,Ø01ˆÔ(Ø34ˆÔ+ð $)ˆÔÜ—\‘\“^ˆŒ
à×#Ñ#Õ%r-   c                óÔ   — t         D ]_  }| j                  j                  D ]D  }| j                  j	                  |«      xs
 t        «       }t        ||«      | j                  ||f<   ŒF Œa y)zIPopulate _cells with cold-start priors for every (rt, model) combination.N)r'   rG   Úavailable_modelsrH   Úgetr/   r   rK   )rX   ÚrtÚmodelÚprefss       r.   rW   z%AdaptiveRouter._init_cold_start_cellsv   se   € äò 	CˆBØŸ™×5Ñ5ò C�Ø×+Ñ+×/Ñ/°Ó6ÒJ¼.Ó:J�Ü+7¸¸rÓ+B�—‘˜R ˜KÒ(ñCñ	Cr-   c              ƒ  óZ  K  — |€y	 t        |«      j                  j                  d| j                  i¬«      ƒ d{  –—† }d}|D ]z  }	 t	        |j
                  «      }|j                  | j                  j                  vrŒ<t        |j                  |j                  ¬«      | j                  ||j                  f<   |dz  }Œ| t        j                  d| j                  |«       y7 Œ§# t        $ r Y Œ¬w xY w# t         $ r+}t        j"                  d| j                  |«       Y d}~yd}~ww xY w­w)	zGOverride cold-start cells with persisted state. Called once at startup.NrF   )Úwherer   )ÚalphaÚbetaé   z+AdaptiveRouter[%s]: loaded %d cells from DBz4AdaptiveRouter[%s]: failed to load state from DB: %s)r"   ÚtableÚ	find_manyrF   r'   r6   Ú
ValueErrorr5   rG   r[   r   rb   rc   rK   r
   ÚinfoÚ	ExceptionÚ	exception)rX   Úprisma_clientÚrowsÚloadedÚrowr]   Úes          r.   Úload_state_from_dbz!AdaptiveRouter.load_state_from_db}   s*  è ø€ àÐ Øð	Ü =¸mÓ L× RÑ R× \Ñ \Ø$ d×&6Ñ&6Ð7ð !]ó !÷ ˆDð ˆFØò 	�ðÜ$ S×%5Ñ%5Ó6�Bð —>‘>¨¯©×)EÑ)EÑEØÜ4>ÀSÇYÁYÐUX×U]ÑU]Ô4^�—‘˜R §¡Ð0Ñ1Ø˜!‘‘ð	ô "×&Ñ&Ø=Ø× Ñ Øõðùô "ò áðûô ò 	Ü!×+Ñ+ØFØ× Ñ Ø÷ñ ûð	üsc   ‚D+‡4C4 »C#¼C4 ÁC%ÁBC4 Ã"D+Ã#C4 Ã%	C1Ã.C4 Ã0C1Ã1C4 Ã4	D(Ã=!D#ÄD+Ä#D(Ä(D+Nc              ƒ  óÚ  K  — t        t        t        t           |xs g «      «      xs d}t	        |«      }| j                  |«      }| j                  ||¬«      ƒ d{  –—† }	t        j                  d| j                  |j                  |	«       |j                  di «      }
t        |
t        «      r	|	|
t        <   t        |	|t!        | j                  d|	d|j                  ¬«      ¬	«      S 7 Œ‹­w)
aý  
        Plugin entry point invoked by `Router.async_pre_routing_hook` when the
        inbound `model` matches this adaptive router's `router_name`.

        Classifies the last user message, picks a logical model via the bandit,
        and stashes the chosen model on `request_kwargs["metadata"]` so the
        post-call hook can surface it as a response header.

        Routing is stateless per-turn: every call Thompson-samples fresh,
        regardless of any prior pick for the same session.
        Ú )r6   Úmin_quality_tierNz-AdaptiveRouter[%s]: classified=%s -> chose %sÚmetadataÚadaptiveÚbandit)Úrouter_model_nameÚrouter_typeÚrouted_modelÚcauser6   )r^   ÚmessagesÚrouting_decision)r   r	   Úlistr#   r   Ú_extract_min_quality_tierÚ
pick_modelr
   ÚdebugrF   ÚvalueÚ
setdefaultÚ
isinstanceÚdictr   r&   r   )rX   r^   Úrequest_kwargsr{   ÚinputÚspecific_deploymentÚ	user_textr6   rs   Úchosen_modelÚkwargs_metadatas              r.   Úasync_pre_routing_hookz%AdaptiveRouter.async_pre_routing_hookž   sæ   è ø€ ô& 1´´dÔ;KÑ6LÈhÊnÐZ\Ó1]Ó^ÒdÐbdˆ	ä-¨iÓ8ˆØ"&×"@Ñ"@ÀÓ"PÐØ$(§O¡OÀÐ`p OÓ$q×qˆÜ×#Ñ#Ø;Ø×ÑØ×ÑØô		
ð "0×!:Ñ!:¸:ÀrÓ!JˆÜ�o¤tÔ,Ø@LˆOÔ<Ñ=ä%ØØÜ;Ø"&×"2Ñ"2Ø&Ø)ØØ)×/Ñ/ôô

ð 
	
ð! rús   ‚AC+ÁC)ÁBC+c              ƒ  ó¢  K  — | j                  |«      }|st        d| j                  › d|› �«      ‚|D �ci c]  }|| j                  ||f   “Œ }}|D �ci c]  }|| j                  j                  |d«      “Œ! }}t        ||| j                  j                  j                  | j                  j                  j                  ¬«      S c c}w c c}w ­w)z;Thompson-sample across eligible models. Stateless per-turn.zAdaptiveRouter[z#]: no models meet min_quality_tier=ç        )Úquality_weightÚcost_weight)Ú_eligible_modelsrg   rF   rK   rI   r\   r   rG   ÚweightsÚqualityÚcost)rX   r6   rs   ÚeligibleÚmÚcellsÚcostss          r.   r   zAdaptiveRouter.pick_modelÓ   sÑ   è ø€ ð ×/Ñ/Ð0@ÓAˆÙÜ˜¨t×/?Ñ/?Ð.@Ð@cÐdtÐcuÐvÓwÐwàCKÖL¸a˜˜4Ÿ;™;¨°aÐ'8Ñ9Ñ9ÐLˆÐLØCKÖL¸a˜˜4×-Ñ-×1Ñ1°!°SÓ9Ñ9ÐLˆÐLÜØØØŸ;™;×.Ñ.×6Ñ6ØŸ™×+Ñ+×0Ñ0ô	
ð 	
ùò MùÚLùs   ‚3CµCÁCÁ$C
Á8ACc              ƒ  ór  ‡K  — g }t        | j                  j                  «       d„ ¬«      D ]u  \  \  }}}|j                  |j                  z   }|j                  |j                  ||j                  |j                  |j                  |dkD  r|j                  |z  nddœ«       Œw | j                  j                  «       ƒ d{  –—† }t        j                  «       Št        ˆfd„| j                  j                  «       D «       «      }| j                  t        | j                   j"                  «      | j                   j$                  j&                  | j                   j$                  j(                  dœt+        | j,                  «      ||| j.                  | j0                  | j2                  | j4                  |d	œS 7 Œó­w)
zDIn-memory snapshot for the introspection endpoint. Cheap; no DB hit.c                ó6   — | d   d   j                   | d   d   fS )Nr   rd   )r�   )Úkvs    r.   ú<lambda>z3AdaptiveRouter.get_state_snapshot.<locals>.<lambda>é   s&   € ÈRÐPQÉUÐSTÉXÏ^É^Ð]_Ð`aÑ]bÐcdÑ]eÐLf€ r-   )Úkeyr   r�   )r6   r^   rb   rc   ÚsamplesÚquality_meanNc              3  óB   •K  — | ]  }|j                   ‰kD  sŒd –— Œ y­w)rd   N)r>   )Ú.0ÚcontextÚnows     €r.   ú	<genexpr>z4AdaptiveRouter.get_state_snapshot.<locals>.<genexpr>û   s    øè ø€ Ò$s¨7ÐZa×ZlÑZlÐorÓZr¤QÑ$sùs   ƒ˜)r’   r“   )rF   r[   r‘   Úmodel_costsr–   Úfeedback_contexts_liveÚfeedback_attributed_totalÚfeedback_without_context_totalÚcross_model_feedback_totalÚresponse_signal_updates_totalrJ   )ÚsortedrK   Úitemsrb   rc   Úappendr�   Útotal_samplesrJ   Ú
queue_sizeÚtimeÚsumrM   ÚvaluesrF   r}   rG   r[   r‘   r’   r“   r„   rI   rO   rP   rQ   rR   )	rX   r–   r]   r^   ÚcellÚtotalrJ   r¥   r¢   s	           @r.   Úget_state_snapshotz!AdaptiveRouter.get_state_snapshotæ   sg  øè ø€ àˆÜ!'¨¯©×(9Ñ(9Ó(;ÑAfÔ!gò 	Ñ‰KˆR�˜Ø—J‘J §¡Ñ*ˆEØ�L‰Là$&§H¡HØ"Ø!ŸZ™ZØ ŸI™Ið
  $×1Ñ1Ø:?À!º) D§J¡J°Ò$6Èñõð	ð  "ŸZ™Z×2Ñ2Ó4×4ˆÜ—Y‘Y“[ˆÜ!$Ó$s°d×6MÑ6M×6TÑ6TÓ6VÔ$sÓ!sÐà×+Ñ+Ü $ T§[¡[×%AÑ%AÓ BàŸ;™;×.Ñ.×6Ñ6ØŸ™×+Ñ+×0Ñ0ñô   × 2Ñ 2Ó3ØØ&<Ø)-×)HÑ)HØ.2×.RÑ.RØ*.×*JÑ*JØ-1×-PÑ-PØñ
ð 	
ð 5ús   ƒB>F7ÃF5ÃC4F7c                óÐ  — | j                  d«      xs i }t        |t        «      rN|j                  «       D ];  \  }}t        |t        «      sŒ|j                  «       t        k(  sŒ/	 t        |«      c S  | j                  d«      xs i }t        |t        «      r#|j                  t        «      }|�	 t        |«      S y# t        t        f$ r Y  yw xY w# t        t        f$ r Y yw xY w)u�  Pull `min_quality_tier` from request headers or metadata.

        Precedence: headers (`x-litellm-min-quality-tier`) over metadata
        (`min_quality_tier`). Headers arrive lowercased from the proxy but we
        lookup case-insensitively to be safe. Unparseable values are ignored
        (treated as "not set") rather than raising â€” a bad header shouldn't
        fail the request.
        ÚheadersNrt   )r\   rƒ   r„   r«   r4   Úlowerr   r9   Ú	TypeErrorrg   r   )r…   r¶   ÚkÚvrt   Úraws         r.   r~   z(AdaptiveRouter._extract_min_quality_tier  sÛ   € ð (×+Ñ+¨IÓ6Ò<¸"ˆÜ�gœtÔ$ØŸ™›ò $‘��1Ü˜a¤Õ%¨!¯'©'«)Ô7NÓ*Nð$Ü" 1›všð$ð )×,Ñ,¨ZÓ8Ò>¸BˆÜ�h¤Ô%Ø!Ÿ™Ô&CÓDˆCØˆð Ü˜s›8�Oð øô &¤zÐ2ò $Ú#ð$ûô "¤:Ð.ò  Ùð ús$   Á&
B=Â1
C Â=CÃCÃC%Ã$C%c                óþ   — |€t        | j                  j                  «      S | j                  j                  D �cg c]8  }| j                  j	                  |«      xs
 t        «       j                  |k\  r|‘Œ: c}S c c}w ©N)r}   rG   r[   rH   r\   r/   r*   )rX   rs   r•   s      r.   r�   zAdaptiveRouter._eligible_models,  sq   € ØÐ#Ü˜Ÿ™×4Ñ4Ó5Ð5ð —[‘[×1Ñ1ö
àØ×#Ñ#×'Ñ'¨Ó*Ò>¬nÓ.>×LÑLÐP`Ò`ò ò
ð 	
ùò 
s   º=A:c                óZ  — ||f}t        j                   «       }t        | j                  «      t        k\  r| j	                  |«       | j                  j                  |«      }|€2t        || j                  ||j                  ¬«      }|| j                  |<   |t        z   | j                  |<   |S )N)Ú
session_idrF   r5   Úclassified_type)r¯   ÚlenrL   r    Ú_evict_expired_session_statesr\   r   rF   r�   r   rN   )rX   r¿   r5   r6   rœ   r¢   Ústates          r.   Úget_or_create_session_statez*AdaptiveRouter.get_or_create_session_state7  s§   € ð ! *Ð-ˆÜ—Y‘Y“[ˆô
 ˆt×#Ñ#Ó$Ô(FÒFØ×.Ñ.¨sÔ3à×$Ñ$×(Ñ(¨Ó-ˆØˆ=Ü Ø%Ø ×,Ñ,Ø%Ø ,× 2Ñ 2ô	ˆEð ).ˆD× Ñ  Ñ%Ø+.Ô1HÑ+Hˆ×#Ñ# CÑ(Øˆr-   c                óò   — | j                   j                  «       D ��cg c]  \  }}||k  sŒ|‘Œ }}}|D ]:  }| j                  j                  |d«       | j                   j                  |d«       Œ< yc c}}w )z€Drop session states whose TTL has passed. O(n) but amortized O(1)
        per insert thanks to `_SESSION_STATE_SWEEP_THRESHOLD`.N)rN   r«   rL   Úpop)rX   r¢   r¹   ÚexpÚexpireds        r.   rÂ   z,AdaptiveRouter._evict_expired_session_statesR  st   € ð +/×*EÑ*E×*KÑ*KÓ*M×\¡  3ÐQTÐX[ÓQ[š!Ð\ˆÑ\Øò 	5ˆAØ× Ñ ×$Ñ$ Q¨Ô-Ø×'Ñ'×+Ñ+¨A¨tÕ4ñ	5ùó ]s
   žA3¬A3c              ƒ  ój
  K  — | j                   4 ƒd{  –—†  t        j                  «       }| j                  ret        t	        | j                  j                  «       «      «      }|j                  |kD  rn)| j                  j                  d¬«       | j                  rŒe| j                  j                  |d«      }|�|t        j                  k(  r|j                  n|}| j                  |||«      }	t        |r|j                  nd|j                  |j                  |duxr% |j                    xr |j"                  dz   t$        k\  ¬«      }
|r|j&                  nd}t)        ||j&                  |	j*                  |j,                  |j                  |j.                  «      }||	i}i }|�º| j                  ||j0                  |j                  «      }t3        ||
«       |
j4                  rd|_        |||j0                  <   |
j7                  «       r9| xj8                  dz  c_        |j0                  |k7  r| xj:                  dz  c_        |
||j                  |j0                  f<   nN|
j7                  «       r| xj<                  dz  c_        t?        |
j@                  ¬«      }t3        |	|«       ||||f<   t3        |	|«       | jC                  |«      dk7  r| xjD                  dz  c_"        ||f}tG        |jI                  |t?        «       «      |«      ||<   tK        |	|«       |r|j"                  nd	dz   }tM        |xr |j                   xs |
j4                  «      }tO        | j                  «      tP        k\  r| j                  j                  d¬«       tS        |||j                  |j&                  |||tT        z   ¬
«      | j                  |<   |jW                  «       D ]D  \  }}| jX                  j[                  || j\                  || j_                  |«      «      ƒ d{  –—†  ŒF t?        «       }|jW                  «       D ]™  \  \  }}}tG        ||«      }| jC                  |«      \  }}|d	k(  r|d	k(  rŒ4||f}ta        | jb                  |   ||«      | jb                  |<   | jX                  je                  | j\                  |jf                  |||«      ƒ d{  –—†  Œ› ti        jj                  d| j\                  |r|j0                  nd||«       |cddd«      ƒd{  –—†  S 7 �Œ7 �Œ7 ŒP7 Œ# 1 ƒd{  –—†7  sw Y   yxY w­w)zVAttribute feedback to the previous response and response signals to the current model.NF)Úlastrd   )Úallow_satisfactionT)Úfailure)r�   r�   r   )r5   r6   r7   r8   r:   r<   r>   z@AdaptiveRouter[%s]: feedback_target=%s current_model=%s delta=%s)6rV   r¯   rM   ÚnextÚiterr±   r>   ÚpopitemrÆ   r'   ÚGENERALr6   rÄ   r   r7   Útool_resultsr<   r:   r   r8   r   Útool_call_historyÚ
tool_callsÚresponse_statusr5   r   ÚsatisfactionÚ	any_firedrO   rQ   rP   r   rÌ   Ú_compute_bandit_deltarR   r   r\   r   r;   rÁ   r!   r3   r   r«   rJ   Úadd_session_staterF   Ú_persistable_session_snapshotr   rK   Úadd_state_deltar�   r
   r€   )rX   r¿   r5   r6   Úturnr¢   Úoldest_contextÚpreviousÚeffective_request_typeÚcurrent_stateÚfeedback_deltaÚprevious_assistantÚresponse_deltaÚstates_to_persistÚbandit_deltasÚfeedback_stateÚinitial_failureÚcurrent_keyÚnext_turn_countr<   Ústate_modelrÃ   Úcombined_deltaÚattribution_typeÚtarget_modelÚdeltaÚd_alphaÚd_betaÚcell_keys                                r.   Úrecord_turnzAdaptiveRouter.record_turnZ  s#  è ø€ ð —:‘:÷ x	"ñ x	"ÜŸ™›ˆCØ×)Ò)Ü!%¤d¨4×+BÑ+B×+IÑ+IÓ+KÓ&LÓ!M�Ø!×,Ñ,¨sÒ2ØØ×'Ñ'×/Ñ/°UÐ/Ô;ð	 ×)Ó)ð
 #×5Ñ5×9Ñ9¸*ÀdÓKˆHð *2Ð)=À,ÔR]×ReÑReÒBe�×%Ò%Ðkwð #ð $(×#CÑ#CØØØ&ó$ˆMô
 %9Ù)1�×%Ò%°tØ×!Ñ!Ø×!Ñ!à DÐ(ò NØ$×9Ñ9Ð9òNà ×+Ñ+¨aÑ/Ô3MÑMô	%ˆNñ GO¨×(BÒ(BÐTXÐÜ$;Ø"Ø×&Ñ&Ø×/Ñ/Ø—‘Ø×!Ñ!Ø×$Ñ$ó%ˆNð BLÈ]Ð@[ÐØOQˆMàÐ#Ø(,×(HÑ(HØØ×'Ñ'Ø×)Ñ)ó)�ô
 # >°>ÔBØ!×.Ò.Ø:>�NÔ7Ø9GÐ! (×"5Ñ"5Ñ6Ø!×+Ñ+Ô-Ø×3Ò3°qÑ8Õ3Ø×*Ñ*¨jÒ8Ø×8Ò8¸AÑ=Õ8ØN\�˜x×4Ñ4°h×6IÑ6IÐJÒKà!×+Ñ+Ô-Ø×8Ò8¸AÑ=Õ8Ü)4¸^×=SÑ=SÔ)T�Ü" =°/ÔBØFU�Ð5°zÐBÑCä˜}¨nÔ=Ø×)Ñ)¨.Ó9¸ZÒGØ×3Ò3°qÑ8Õ3Ø"8¸*Ð!EˆKÜ)<Ø×!Ñ! +¬{«}Ó=Øó*ˆM˜+Ñ&ô " -°Ô6á=E h×&9Ò&9È1ÐPQÑ%QˆOÜ#'¨Ò)S°h×6SÑ6SÒ(sÐXf×XsÑXsÓ#tÐ Ü�4×*Ñ*Ó+Ô/LÒLØ×'Ñ'×/Ñ/°UÐ/Ô;Ü2BØ%Ø3Ø!×.Ñ.Ø"&×"8Ñ"8Ø*Ø%9ØÔ!8Ñ8ô3ˆD×#Ñ# JÑ/ð '8×&=Ñ&=Ó&?ò Ñ"�˜UØ—j‘j×2Ñ2ØØ×$Ñ$ØØ×6Ñ6°uÓ=ó	÷ ñ ðô )›]ˆNØ;H×;NÑ;NÓ;Pò Ñ7Ñ0Ð! <°%Ü!4°^ÀUÓ!K�Ø"&×"<Ñ"<¸UÓ"C‘�˜Ø˜a’< F¨a¢KØØ,¨lÐ;�Ü(3Ø—K‘K Ñ)ØØó)�—‘˜HÑ%ð
 —j‘j×0Ñ0Ø×$Ñ$Ø$×*Ñ*Ø ØØó÷ ñ ðô& "×'Ñ'ØRØ× Ñ Ù'/�×#Ò#°TØØôð "÷qx	"÷ x	"ò x	"ùðlùð&øðSx	"ø÷ x	"÷ x	"ñ x	"üsq   ‚T3“T”T3—BTÂM6TÐTÐB5TÓ	TÓ
8TÔT3ÔTÔT3ÔTÔTÔT3ÔT0Ô$T'Ô%T0Ô,T3c                óN   — t        | «      }dD ]  }|j                  |d «       Œ |S )N)Úlast_user_contentÚlast_assistant_contentrÒ   Úpending_tool_calls)r   rÆ   )rÃ   ÚsnapshotÚ	sensitives      r.   rÙ   z,AdaptiveRouter._persistable_session_snapshotÜ  s3   € ä  ›-ˆð
ò 	*ˆIð �L‰L˜ DÕ)ð	*ð ˆr-   c                óÌ   — t        | j                  «      }t        | j                  | j                  z   | j                  z   | j
                  z   «      d| j                  z  z   }||fS )u£  
        Translate per-turn signal deltas into bandit-cell deltas.

        v0 mapping (UNVALIDATED â€” D6):
        - satisfaction               -> +1 alpha
        - misalignment, stagnation,
          disengagement, failure     -> +1 beta each
        - loop                       -> +0.5 beta (weak; could be model OR user)
        - exhaustion                 -> 0 (uptime issue, tracked separately later)
        g      à?)r=   rÕ   ÚmisalignmentÚ
stagnationÚdisengagementrÌ   Úloop)rí   rî   rï   s      r.   r×   z$AdaptiveRouter._compute_bandit_deltaè  sb   € ô ˜u×1Ñ1Ó2ˆÜ�u×)Ñ)¨E×,<Ñ,<Ñ<¸u×?RÑ?RÑRÐUZ×UbÑUbÑbÓcÐfiÐlq×lvÑlvÑfvÑvˆØ˜ˆÐr-   )
rF   r4   rG   r$   rH   z$dict[str, AdaptiveRouterPreferences]rI   zdict[str, float]ÚreturnÚNone)rý   rþ   )rk   r   rý   rþ   )NNF)r^   r4   r…   údict[str, Any]r{   zlist[dict[str, Any]] | Noner†   zstr | list | Noner‡   zbool | Nonerý   zPreRoutingHookResponse | Noner½   )r6   r'   rs   ú
int | Nonerý   r4   )rý   rÿ   )r…   rÿ   rý   r   )rs   r   rý   z	list[str])r¿   r4   r5   r4   r6   r'   rý   r   )r¢   r=   rý   rþ   )
r¿   r4   r5   r4   r6   r'   rÛ   r   rý   r   )rÃ   r   rý   rÿ   )rí   r   rý   ztuple[float, float])r?   r@   rA   Ú__doc__rY   rW   rp   r‹   r   r´   Ústaticmethodr~   r�   rÄ   rÂ   rñ   rÙ   r×   r,   r-   r.   rD   rD   U   sz  „ ÙRð&àð&ð %ð&ð =ð	&ð
 (ð&ð 
ó&ó<CóðJ 15Ø#'Ø+0ð1
àð1
ð 'ð1
ð .ð	1
ð
 !ð1
ð )ð1
ð 
'ó1
ðp (,ð
à!ð
ð %ð
ð 
ó	
ó&%
ðN ðØ&ðà	òó ðó<
ðàðð ðð "ð	ð
 
óó65ð@"àð@"ð ð@"ð "ð	@"ð
 ð@"ð 
ó@"ðD ò	ó ð	ð òó ñr-   rD   )rý   r%   );r  Ú
__future__r   rT   r¯   Úcollectionsr   Údataclassesr   r   Útypingr   r   r	   Úlitellm._loggingr
   Ú8litellm.litellm_core_utils.prompt_templates.common_utilsr   Ú.litellm.router_strategy.adaptive_router.banditr   r   r   r   Ú2litellm.router_strategy.adaptive_router.classifierr   Ú.litellm.router_strategy.adaptive_router.configr   r   r   r   r   Ú/litellm.router_strategy.adaptive_router.signalsr   r   r   r   r   r   r   r   Ú4litellm.router_strategy.adaptive_router.update_queuer   Úlitellm.types.utilsr   r    rB   r!   Ú'litellm.repositories.table_repositoriesr"   Úlitellm.types.llms.openair#   Úlitellm.types.routerr$   r%   r&   r'   r/   r3   rD   r,   r-   r.   ú<module>r     s¶   ðòõ #ã Û Ý #ß )ß #Ñ #å 2õ÷ó õ O÷õ ÷	÷ 	ó 	õõ ?ð .2Ð  
Ó 1Ø,0Ð ˜zÓ 0Ý QÝ 6÷ó óCñ
 �$˜dÔ#÷ð ó $ð÷aò ar-   