Ë
    tPêjD  ã                  óD  — U 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mZm	Z	 ddlm
Z
 ddlmZ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 ddlmZ erddlmZ ddlmZ dZded<   dZded<   dZded<    e
dd¬«       G d„ d«      «       Z  G d„ de«      Z!d‡d„Z"dˆd„Z#d‰d„Z$dZ%ded<   dŠd!„Z&	 	 	 	 	 	 	 	 d‹d#„Z' e(d$„  ejR                  e «      D «       «      Z*ded%<   dŒd&„Z+ e+d'«      Z,ded(<    e+d)«      Z-ded*<    e+d+«      Z.ded,<    e+d-«      Z/ded.<    e+d/«      Z0ded0<    e+d1«      Z1ded2<    e+d3«      › d4�Z2ded5<   d6e2› d7e2› d8�Z3ded9<   e-› d:�Z4ded;<   e4› d<e,› �Z5ded=<   e4› d>e,› �Z6ded?<   e4› d@e,› dAe,› �Z7dedB<   e7› dCe.› dDe/› dEe,› dF�Z8dedG<   dHe-› dIe,› dJ�Z9dedK<   e1› dL�Z:dedM<   dNjw                  g dO‘ e+dP«      › ‘dQ‘ e+d «      › ‘dQ‘ e+dR«      › ‘dQ‘ e+dS«      › ‘dQ‘e-› ‘dT‘e-› ‘dU‘e,› ‘dV‘e,› ‘dW‘e-› ‘dX‘e0› ‘dY‘e.› ‘dZ‘e/› ‘d[‘e/› ‘d\‘e0› ‘d]‘e› ‘d^‘e0› ‘d]‘e› ‘d_‘ e+d`«      › ‘da‘ e+db«      › ‘dc‘ e+d"«      › ‘dd‘e3› ‘de‘e4› ‘df‘e5› ‘dg‘e5› ‘dC‘e/› ‘dh‘e6› ‘di‘e6› ‘dC‘e/› ‘dj‘e7› ‘dk‘e7› ‘dC‘e/› ‘dl‘e8› ‘dC‘e9› ‘dm‘e,› ‘dn‘e8› ‘dC‘e9› ‘do‘e,› ‘dp‘e,› ‘dq‘e:› ‘dr‘e,› ‘ds‘e-› ‘dt‘e,› ‘du‘e-› ‘dv‘e4› ‘dw‘e0› ‘dx‘e,› ‘dy‘e,› ‘dz‘e0› ‘d{‘e4› ‘d|‘e,› ‘d}‘e2› ‘d~‘ e+dS«      › ‘d‘e2› ‘d€‘e2› ‘d�‘«      Z<ded‚<   d�dƒ„Z=dŽd„„Z>	 	 	 	 	 	 	 	 d�d…„Z?	 d�	 	 	 	 	 	 	 d‘d†„Z@y)’a‡  
Per-session auto-router benchmarks rollup.

At request time the spend writer builds one AutoRouterTurnTransaction per successful
auto-routed request (a request whose metadata carries a routing_decision) and queues it
on the prisma client. The spend-log flush job drains the queue into
LiteLLM_AutoRouterSession with one conditional upsert per turn: the statement classifies
the turn (same model, first visit, return to a model the session already used, out of
order) against the row's own columns, so nothing is read before the write and concurrent
pods compose. The benchmarks endpoint aggregates these rows and never touches
LiteLLM_SpendLogs.
é    )ÚannotationsN)ÚMappingÚSequence)Ú	dataclass)ÚdatetimeÚtimezone)Úgroupby)ÚTYPE_CHECKINGÚFinalÚ
NamedTuple)Úverbose_proxy_logger)Ú!INTERNAL_CALL_ORIGIN_METADATA_KEY)ÚDB_RETRY_SAFE_ERROR_TYPES)ÚSpendLogsPayload)ÚPrismaClienti,  r   ÚCACHE_TTL_5M_SECONDSi  ÚCACHE_TTL_1H_SECONDSa�  
WITH windowed AS (
    SELECT * FROM "LiteLLM_AutoRouterSession"
    WHERE last_turn_at >= $1::timestamp AND first_turn_at < $2::timestamp
),
tier_maps AS (
    SELECT router_name, router_type, jsonb_object_agg(tier, tier_turns) AS tier_turns
    FROM (
        SELECT router_name, router_type, kv.key AS tier, SUM((kv.value)::int)::int AS tier_turns
        FROM windowed, LATERAL jsonb_each_text(tier_turns) AS kv
        GROUP BY router_name, router_type, kv.key
    ) per_tier
    GROUP BY router_name, router_type
)
SELECT
    agg.*,
    COALESCE(tier_maps.tier_turns, '{}'::jsonb) AS tier_turns
FROM (
SELECT
    router_name,
    router_type,
    COUNT(*)::int AS sessions,
    COALESCE(SUM(turns), 0)::int AS turns,
    COALESCE(SUM(unordered_turns), 0)::int AS unordered_turns,
    COALESCE(SUM(covered_turns), 0)::int AS covered_turns,
    COALESCE(SUM(cache_hits), 0)::int AS cache_hits,
    COALESCE(SUM(same_model_turns), 0)::int AS same_model_turns,
    COALESCE(SUM(same_model_hits), 0)::int AS same_model_hits,
    COALESCE(SUM(first_visit_turns), 0)::int AS first_visit_turns,
    COALESCE(SUM(first_visit_hits), 0)::int AS first_visit_hits,
    COALESCE(SUM(return_turns), 0)::int AS return_turns,
    COALESCE(SUM(return_hits), 0)::int AS return_hits,
    COALESCE(SUM(return_expired_misses), 0)::int AS return_expired_misses,
    COALESCE(SUM(return_within_ttl_misses), 0)::int AS return_within_ttl_misses,
    COALESCE(SUM(ttl_5m_turns), 0)::int AS ttl_5m_turns,
    COALESCE(SUM(ttl_1h_turns), 0)::int AS ttl_1h_turns,
    COALESCE(SUM(total_tokens), 0)::bigint AS total_tokens,
    COALESCE(SUM(spend), 0)::float8 AS spend,
    COALESCE(SUM(saved_spend), 0)::float8 AS saved_spend,
    COALESCE(SUM(EXTRACT(EPOCH FROM (last_turn_at - first_turn_at))), 0)::float8 AS session_seconds
FROM windowed
GROUP BY router_name, router_type
) agg
LEFT JOIN tier_maps USING (router_name, router_type)
ORDER BY agg.spend DESC
ÚAUTOROUTER_BENCHMARKS_SQLT)ÚfrozenÚslotsc                  óž   — 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
<   ded<   ded<   ded<   ded<   ded<   ded<   dZded<   y)ÚAutoRouterTurnTransactionÚstrÚapi_keyÚ
session_idÚrouter_nameÚrouter_typeÚmodelr   Úturn_atÚintÚtotal_tokensÚfloatÚspendÚsaved_spendÚboolÚcoveredÚ	cache_hitú
int | NoneÚcache_ttl_secondsÚcache_touchedNz
str | NoneÚtier)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r+   © ó    úo/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/db/autorouter_session_rollup.pyr   r   U   sT   … àƒLØƒOØÓØÓØƒJØÓØÓØƒLØÓØƒMØƒOØ!Ó!ØÓØ€Dˆ*Ôr1   r   c                  ó:   — e Zd ZU dZded<   ded<   ded<   ded<   y	)
ÚTurnCacheFactsa/  One statement of a turn's cache interaction, derived from its usage record.

    ``touched`` is False only when telemetry positively shows the provider neither
    read from nor wrote to the cache; absent telemetry reads as touched, which is
    the conservative input for the per-model idle clock.
    r%   r&   r    Úread_tokensr(   Úwrite_ttl_secondsÚtouchedN)r,   r-   r.   Ú__doc__r/   r0   r1   r2   r4   r4   g   s   … ñð ƒMØÓØ!Ó!Ø„Mr1   r4   c                ó„   — ddl m} t        | «      } || «      }t        | «      }t	        |||| xs |dkD  xs |d u¬«      S )Nr   )Úextract_cache_read_tokens)r&   r5   r6   r7   )Ú$litellm.proxy.spend_tracking.savingsr:   r%   Ú_write_ttl_secondsr4   )Úusage_objectr:   r&   r5   r6   s        r2   Úturn_cache_factsr>   u   sS   € ÝNä˜,Ó'€GÙ2°<Ó@€KÜ1°,Ó?ÐÜØØØ+Ø�ÒO˜{¨Q™ÒOÐ2CÈ4Ð2Oô	ð r1   c                óæ   — 	 t        j                  | j                  dd«      «      }|j                  €|S |j                  t        j                  «      j                  d ¬«      S # t        $ r Y y w xY w)NÚZz+00:00)Útzinfo)r   ÚfromisoformatÚreplaceÚ
ValueErrorrA   Ú
astimezoner   Úutc)Ústart_time_isoÚparseds     r2   Ú_turn_time_utcrI   ƒ   sl   € ðÜ ×.Ñ.¨~×/EÑ/EÀcÈ8Ó/TÓUˆð ‡}�}ÐØˆØ×ÑœXŸ\™\Ó*×2Ñ2¸$Ð2Ó?Ð?øô	 ò Ùðús   ‚%A$ Á$	A0Á/A0c                ó  — ddl m} | sy| j                  d«      }t        |t        «      r|j                  d«      nd}t        |t        «      r.|j                  d«      rt
        S |j                  d«      rt        S  || «      dkD  rt        S y)zÝThe TTL this turn's cache write used, or None when nothing was written.

    Providers that report a TTL split do so under prompt_tokens_details; a write with no
    split is the provider's default five-minute cache.
    r   )Úextract_cache_creation_tokensNÚprompt_tokens_detailsÚcache_creation_token_detailsÚephemeral_1h_input_tokensÚephemeral_5m_input_tokens)r;   rK   ÚgetÚ
isinstancer   r   r   )r=   rK   ÚdetailsÚcreations       r2   r<   r<   �   s‚   € õ SáØØ!×%Ñ%Ð&=Ó>€GÜEOÐPWÔY`ÔEa�g—k‘kÐ"@ÔAÐgk€HÜ�(œGÔ$Ø�<‰<Ð3Ô4Ü'Ð'Ø�<‰<Ð3Ô4Ü'Ð'Ù$ \Ó2°QÒ6Ü#Ð#Ør1   é   ÚSESSION_ID_MAX_CHARSr   c                ó˜   — t        | «      t        k  r| S dt        j                  | j	                  dd¬«      «      j                  «       z   S )zóThe session id as stored, bounded so a caller-chosen identifier cannot exceed
    Postgres's B-tree index entry limit through the composite primary key. Oversized
    ids map to a stable digest, so their turns still aggregate into one session.zsha256:zutf-8Úsurrogatepass)Úerrors)ÚlenrU   ÚhashlibÚsha256ÚencodeÚ	hexdigest)r   s    r2   Ú_bounded_session_idr^   ¦   sD   € ô ˆ:ƒÔ.Ò.ØÐØ”w—~‘~ j×&7Ñ&7¸ÈÐ&7Ó&XÓY×cÑcÓeÑeÐer1   r$   c                ó$  — | j                  d«      dk7  ry|j                  t        «      ry|j                  d«      }t        |t        «      r|sy|j                  d«      xs | j                  d«      }| j                  d«      }| j                  d«      }| j                  d	«      }t        |t        «      r|r|r|r|syt        t	        | j                  d
«      xs d«      «      }|€yddlm}	 |j                  d«      }
t        t        |
t        «      r|
nd«      }|j                  d«      } |	|«      }t        |t        |«      |t	        |j                  d«      xs d«      t        |t        «      r|r|nd||t        | j                  d«      xs d«      t        | j                  d«      xs d«      z   t        | j                  d«      xs d«      |xs dz   ||j                  |j                  dkD  |j                  |j                   ¬«      S )a¥  One rollup transaction for a successful auto-routed turn, else None.

    The routing_decision record is what says a request was auto-routed at all, so a
    request without one (including the auto-router's own classifier sub-calls) never
    reaches the rollup. Internal sub-calls that DO carry one (a shadow eval's duplicate
    of a request through the router) are excluded by their internal_call_origin stamp:
    they are not traffic a user sent, so counting them would manufacture sessions and
    savings in the adoption metrics. Failed requests served nothing and are excluded.
    The classifier's charge still lands here exactly once, via the decision's own
    classifier_cost folded into this turn's spend: the excluded classifier row is how
    it was billed, the decision is how it is attributed. Cache facts are derived from
    the payload's own usage record through the savings owner, never handed in beside it.
    ÚstatusÚsuccessNÚrouting_decisionÚrouter_model_nameÚmodel_groupr   r   r   Ú	startTimeÚ r   )Úclassifier_cost_from_decisionr=   r+   r   ÚunknownÚprompt_tokensÚcompletion_tokensr#   g        )r   r   r   r   r+   r   r   r!   r#   r$   r&   r'   r)   r*   )rP   r   rQ   r   r   rI   r;   rg   r>   r   r^   r    r"   r&   r5   r6   r7   )ÚpayloadÚmetadatar$   rb   r   r   r   r   r   rg   Úusage_object_rawÚcacheÚtier_rawÚclassifier_costs                 r2   Ú!build_autorouter_turn_transactionrq   ¯   sÖ  € ð$ ‡{�{�8Ó 	Ò)ØØ‡|�|Ô5Ô6ØØ&Ÿl™lÐ+=Ó>ÐÜÐ&¬Ô0Ñ8HØØ)×-Ñ-Ð.AÓBÒ`ÀgÇkÁkÐR_ÓF`€KØ—[‘[ Ó+€GØŸ™ LÓ1€JØ—;‘;˜wÓ'€EÜ�{¤CÔ(©[¹WÉÑX]ØÜ#¤C¨¯©°KÓ(@Ò(FÀBÓ$GÓH€GØ€ØÝRà&Ÿl™l¨>Ó:ÐÜ#¼
ÐCSÔU\Ô8]Ñ$4ÐcgÓh€EØ&×*Ñ*¨6Ó2€HÙ:Ð;KÓL€OÜ$ØÜ& zÓ2ØÜÐ(×,Ñ,¨]Ó;ÒH¸yÓIÜ# H¬cÔ2±x‰XÀTØØÜ˜Ÿ™ _Ó5Ò:¸Ó;¼cÀ'Ç+Á+ÐNaÓBbÒBgÐfgÓ>hÑhÜ�G—K‘K Ó(Ò/¨CÓ0°OÒ4JÀsÑKØØ—‘Ø×#Ñ# aÑ'Ø×1Ñ1Ø—m‘môð r1   c              #  ó4   K  — | ]  }|j                   –— Œ y ­w©N)Úname)Ú.0Úfields     r2   ú	<genexpr>rw   é   s   è ø€ Ò#j°5 E§J¥JÑ#jùs   ‚Ú_UPSERT_PARAM_FIELDSc                ó8   — dt         j                  | «      dz   › �S )z¨Positional placeholder for a transaction field, numbered by the dataclass's own
    field order so the SQL and the argument tuple cannot disagree; typos fail at import.ú$é   )rx   Úindex)Ú
field_names    r2   Ú_pr~   ì   s#   € ð Ô#×)Ñ)¨*Ó5¸Ñ9Ð:Ð;Ð;r1   r   Ú_MODELr   Ú_TURN_ATr&   Ú_COVEREDr'   Ú
_CACHE_HITr)   Ú
_CACHE_TTLr*   Ú_TOUCHEDr+   z::textÚ_TIERz(CASE WHEN z2 IS NULL THEN '{}'::jsonb ELSE jsonb_build_object(z	, 1) END)Ú_TIER_DELTAz::timestamp >= t.last_turn_atÚ	_IN_ORDERz AND t.last_model = Ú_SAMEz AND NOT t.models ? Ú_FIRSTz AND t.models ? z AND t.last_model <> Ú_RETURNz AND z::int = 1 AND z::int = 0 AND (t.models -> z ->> 'ttl') IS NOT NULLÚ_RETURN_MISSzEXTRACT(EPOCH FROM z::timestamp) - (t.models -> z ->> 'at')::float8Ú_IDLE_SECONDSz	::int = 1Ú_CACHE_TOUCHEDrf   aÃ  
INSERT INTO "LiteLLM_AutoRouterSession" AS t (
    api_key, session_id, router_name, router_type, first_turn_at, last_turn_at,
    last_model, models, turns, unordered_turns, covered_turns, cache_hits,
    same_model_turns, same_model_hits, first_visit_turns, first_visit_hits,
    return_turns, return_hits, return_expired_misses, return_within_ttl_misses,
    ttl_5m_turns, ttl_1h_turns, total_tokens, spend, saved_spend, tier_turns
)
VALUES (
    r   z, r   r   z::timestamp, z::timestamp,
    z, jsonb_build_object(z., jsonb_build_object('at', EXTRACT(EPOCH FROM z::timestamp), 'ttl', z::int)),
    1, 0, z::int, z::int,
    0, 0, 1, z&::int,
    0, 0, 0, 0,
    (CASE WHEN z::int = z$ THEN 1 ELSE 0 END),
    (CASE WHEN z THEN 1 ELSE 0 END),
    r!   z
::bigint, r#   z
::float8, z::float8,
    a  
)
ON CONFLICT (api_key, session_id, router_name) DO UPDATE SET
    turns = t.turns + 1,
    total_tokens = t.total_tokens + EXCLUDED.total_tokens,
    spend = t.spend + EXCLUDED.spend,
    saved_spend = t.saved_spend + EXCLUDED.saved_spend,
    covered_turns = t.covered_turns + EXCLUDED.covered_turns,
    cache_hits = t.cache_hits + EXCLUDED.cache_hits,
    ttl_5m_turns = t.ttl_5m_turns + EXCLUDED.ttl_5m_turns,
    ttl_1h_turns = t.ttl_1h_turns + EXCLUDED.ttl_1h_turns,
    unordered_turns = t.unordered_turns + (CASE WHEN NOT (zM) THEN 1 ELSE 0 END),
    same_model_turns = t.same_model_turns + (CASE WHEN zJ THEN 1 ELSE 0 END),
    same_model_hits = t.same_model_hits + (CASE WHEN zW::int = 1 THEN 1 ELSE 0 END),
    first_visit_turns = t.first_visit_turns + (CASE WHEN zL THEN 1 ELSE 0 END),
    first_visit_hits = t.first_visit_hits + (CASE WHEN zM::int = 1 THEN 1 ELSE 0 END),
    return_turns = t.return_turns + (CASE WHEN zB THEN 1 ELSE 0 END),
    return_hits = t.return_hits + (CASE WHEN zg::int = 1 THEN 1 ELSE 0 END),
    return_expired_misses = t.return_expired_misses
        + (CASE WHEN z > (t.models -> zw ->> 'ttl')::float8 THEN 1 ELSE 0 END),
    return_within_ttl_misses = t.return_within_ttl_misses
        + (CASE WHEN z <= (t.models -> zT ->> 'ttl')::float8 THEN 1 ELSE 0 END),
    models = t.models || jsonb_build_object(z/, jsonb_build_object(
        'at', (CASE WHEN z4
               THEN GREATEST(COALESCE((t.models -> z+ ->> 'at')::float8, 0), EXTRACT(EPOCH FROM z8::timestamp))
               ELSE COALESCE((t.models -> z' ->> 'at')::float8, EXTRACT(EPOCH FROM z.::timestamp)) END),
        'ttl', (CASE WHEN z
                THEN COALESCE(z::int, (t.models -> z= ->> 'ttl')::int)
                ELSE COALESCE((t.models -> z ->> 'ttl')::int, z0::int) END)
    )),
    last_model = (CASE WHEN z THEN z5 ELSE t.last_model END),
    tier_turns = (CASE WHEN z! IS NOT NULL AND t.router_type = z1
        THEN t.tier_turns || jsonb_build_object(z, COALESCE((t.tier_turns ->> z·)::int, 0) + 1)
        ELSE t.tier_turns END),
    first_turn_at = LEAST(t.first_turn_at, EXCLUDED.first_turn_at),
    last_turn_at = GREATEST(t.last_turn_at, EXCLUDED.last_turn_at)
ÚUPSERT_AUTOROUTER_SESSION_SQLc                ó|   — t        | t        «      rt        | «      S t        | t        «      r| j	                  «       S | S rs   )rQ   r%   r    r   Ú	isoformat)Úvalues    r2   Ú_as_sql_paramr’   =  s2   € Ü�%œÔÜ�5‹zÐÜ�%œÔ"Ø�‰Ó Ð Ø€Lr1   c                ó4   ‡ — t        ˆ fd„t        D «       «      S )Nc              3  óH   •K  — | ]  }t        t        ‰|«      «      –— Œ y ­wrs   )r’   Úgetattr)ru   rt   Útransactions     €r2   rw   z!_upsert_params.<locals>.<genexpr>F  s   øè ø€ Ò\¸t”œw {°DÓ9×:Ñ\ùs   ƒ")Útuplerx   ©r–   s   `r2   Ú_upsert_paramsr™   E  s   ø€ ÜÓ\ÔG[Ô\Ó\Ð\r1   c           	   ƒ  ó8  K  — t        |dz   «      D ]6  }	  | j                  j                  t        gt	        |«      ¢­Ž ƒ d {  –—†   y  y 7 Œ# t
        $ rA ||k\  r‚ t        j                  d|z  t        j                  dd«      z   «      ƒ d {  –—†7   Y Œ…w xY w­w)Nr{   é   r   )
ÚrangeÚdbÚexecute_rawrŽ   r™   r   ÚasyncioÚsleepÚrandomÚuniform)Úprisma_clientr–   Ún_retry_timesÚattempts       r2   Ú_upsert_turn_with_retryr¦   I  s—   è ø€ ô
 ˜¨Ñ*Ó+ò ˆð	Ø.�-×"Ñ"×.Ñ.Ô/LÐkÌ~Ð^iÓOjÒk×kÐkñ ñàkùÜ(ò 	CØ˜-Ò'ØÜ—-‘-  7¡
¬V¯^©^¸A¸qÓ-AÑ AÓB×BÓBð	CüsG   ‚B•-AÁAÁAÁBÁAÁABÂBÂBÂBÂBÂBc              ƒ  óV  K  — |syt        |d„ ¬«      }t        |d„ ¬«      D ]9  \  }}t        |«      }t        |«      D ]  \  }}	 t	        | ||«      ƒ d{  –—†  Œ Œ; y7 Œ	# t
        $ r<}	t        j                  d|d   t        |«      |z
  t        |«      |	«       Y d}	~	 Œd}	~	ww xY w­w)aÝ  Drain a queue batch into the rollup, one upsert per turn.

    Statements run sequentially in per-session event order: a turn's classification
    depends on the turns before it, and Postgres rejects one multi-row INSERT touching
    the same key twice. Only ConnectError is retried, per statement, because it proves
    that statement never reached the database. Any other failure drops the remaining
    turns of THAT session only, with an error log, and the flush continues with the
    next session: sessions are independent state machines, so one poisoned statement
    must not discard unrelated sessions, and a repeated increment is worse than an
    undercount. Callers must not add their own retry around this function.
    Nc                ó^   — | j                   | j                  | j                  | j                  fS rs   )r   r   r   r   r˜   s    r2   ú<lambda>z4flush_autorouter_turn_transactions.<locals>.<lambda>m  s-   € Ø×ÑØ×"Ñ"Ø×#Ñ#Ø×Ñð	!
€ r1   )Úkeyc                óH   — | j                   | j                  | j                  fS rs   )r   r   r   r˜   s    r2   r©   z4flush_autorouter_turn_transactions.<locals>.<lambda>v  s   €  ×!4Ñ!4°k×6LÑ6LÈk×NeÑNeÐ f€ r1   z~Spend tracking - auto-router session rollup flush failed for router %s; %s of %s turn transactions dropped for one session: %sr›   )	Úsortedr	   r—   Ú	enumerater¦   Ú	Exceptionr   ÚerrorrY   )
r£   Útransactionsr¤   ÚorderedÚsession_keyÚsession_groupÚsession_turnsÚpositionr–   Ú	flush_errs
             r2   Ú"flush_autorouter_turn_transactionsr·   Y  sÊ   è ø€ ñ  ØÜØñ
ô€Gô '.ØÙfô'ò Ñ"ˆ�]ô ˜mÓ,ˆÜ%.¨}Ó%=ò 	Ñ!ˆH�kðÜ-¨m¸[È-ÓX×XÑXñ	ñð YùÜò 	Ü$×*Ñ*ðMà ‘NÜ˜Ó&¨Ñ1Ü˜Ó&Øôõ ûð	üsB   ‚AB)ÁA!ÁAÁA!ÁB)ÁA!Á!	B&Á*1B!ÂB)Â!B&Â&B))r=   úMapping[str, object] | NoneÚreturnr4   )rG   r   r¹   zdatetime | None)r=   r¸   r¹   r(   )r   r   r¹   r   )rk   r   rl   zMapping[str, object]r$   r"   r¹   z AutoRouterTurnTransaction | None)r}   r   r¹   r   )r‘   z$str | float | bool | datetime | Noner¹   zstr | float | None)r–   r   r¹   ztuple[str | float | None, ...])r£   r   r–   r   r¤   r    r¹   ÚNone)é   )r£   r   r°   z#Sequence[AutoRouterTurnTransaction]r¤   r    r¹   rº   )Ar8   Ú
__future__r   rŸ   ÚdataclassesrZ   r¡   Úcollections.abcr   r   r   r   r   Ú	itertoolsr	   Útypingr
   r   r   Úlitellm._loggingr   Úlitellm.constantsr   Úlitellm.proxy._typesr   r   Úlitellm.proxy.utilsr   r   r/   r   r   r   r4   r>   rI   r<   rU   r^   rq   r—   Úfieldsrx   r~   r   r€   r�   r‚   rƒ   r„   r…   r†   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   ÚjoinrŽ   r’   r™   r¦   r·   r0   r1   r2   ú<module>rÇ      s]  ðòõ #ã Û Û Û ß -Ý !ß 'Ý ß 3Ñ 3å 1Ý ?Ý :áÝ5Ý0à!Ð �eÓ !Ø"Ð �eÓ "ð-$Ð ˜5ó -ñ` �$˜dÔ#÷ð ó $ðô"�Zô óó@óð, "Ð �eÓ !ófð7Øð7à"ð7ð ð7ð &ó	7ñt $Ñ#jÐ<N¸K×<NÑ<NÐOhÓ<iÔ#jÓjÐ �eÓ jó<ñ �7“€ˆÓ Ù�Y“-€ˆ%Ó Ù�Y“-€ˆ%Ó Ù�{“O€
ˆEÓ #ÙÐ*Ó+€
ˆEÓ +Ù�_Ó%€ˆ%Ó %Ù�V“*�˜VÐ$€€uÓ $Ø" 5 'Ð)]Ð^cÐ]dÐdmÐn€ˆUÓ nà�ZÐ<Ð=€	ˆ5Ó =Ø�Ð0°°Ð9€€uÓ 9Ø�+Ð1°&°Ð:€ˆÓ :Ø�;Ð.¨v¨hÐ6KÈFÈ8ÐT€ˆÓ Tà€iˆu�X�J˜n¨Z¨LÐ8SÐTZÐS[Ð[rÐsð ˆeó ð -¨X¨JÐ6RÐSYÐRZÐZlÐm€ˆuÓ mØ#˜* IÐ.€�Ó .÷5(ó 5(ð 	,ð 5(ñ ˆ	ƒ]€Oð5(ð ð5(ñ ˜Ó&Ð'ð5(ð (*ð5(ñ +-¨]Ó*;Ð)<ð5(ð =?ð5(ñ @BÀ-Ó?PÐ>Qð5(ð RTð5(ð U]ÐS]ð5(ð ^kð5(ð ltÐjtð5(ðuð5(ð €Hð5(ð "ð5(ð #) ð5(ð *Xð5(ð YaÐWað5(ð bwð5(ð xBð  wCð5(ðCð5(ð ˆ*ð5(ð ð5(ð '˜<ð5(ð(ð5(ð ˆ\ð5(ðð5(ð ˆ|ð5(ð $ð5(ð %9Ð#9ð5(ð:ð5(ð ˆ|ð5(ð $ð5(ð %9Ð#9ð5(ð:ð5(ñ  ˆÓÐð!5(ð  #ð!5(ñ  $& g£; -ð!5(ð  0:ð!5(ñ  ;=¸]Ó:KÐ9Lð!5(ð Mð!5(ð" €Mð#5(ð";ð#5(ð8 <E¸+ð95(ð8F8ð95(ð: 9>°wð;5(ð:?6ð;5(ð< 7<°Wð=5(ð< =Bð=5(ð< CMÀð=5(ð<N:ð=5(ð> ;A¸ð?5(ð>B8ð?5(ð@ 9?°xðA5(ð@ @EðA5(ð@ FPÀLðA5(ð@Q0ðA5(ðB 18¨yðC5(ðB9.ðC5(ðD /6¨YðE5(ðD 7<ðE5(ðD =G¸<ðE5(ðDHðE5(ðH #�^ðI5(ðH $)ðI5(ðH *7¨ðI5(ðH 8HðI5(ðH IOÀxðI5(ðHPðI5(ðL #�^ðM5(ðL $)ðM5(ðL *7¨ðM5(ðL 8IðM5(ðL JPÈðM5(ðLQ-ðM5(ðN .4¨HðO5(ðN5ðO5(ðP )Ð)ðQ5(ðP*4ðQ5(ðR 5;°8ðS5(ðR <gðS5(ðR hpÐfpðS5(ðRq+ðS5(ðT ,2¨(ðU5(ðT 3ZðU5(ðT [cÐYcðU5(ðTdðU5(ðV %˜+ðW5(ðV&ðW5(ðX  *˜lðY5(ðX +?ðY5(ðX @F¸hðY5(ðXG,ðY5(ðZ -3¨8ð[5(ðZ 4Fð[5(ðZ GQÀ\ð[5(ðZRð[5(ð^ '˜Kð_5(ð^ (.ð_5(ð^ /5¨Xð_5(ð^6ð_5(ð` #˜Gða5(ð` $Eða5(ñ` FHÈÓEVÐDWða5(ð`X1ða5(ðb 27°ðc5(ðb 8Uðc5(ðb V[ÐT[ðc5(ðb\ôc5(Ð ˜uó 5ópó]ðØðà*ðð ðð 
ó	ð& ð,Øð,à5ð,ð ð,ð 
ô	,r1   