Ë
    uPêjÿ4  ã            	       óx  — U d Z ddl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 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 e
rdd
lmZ  eh d£«      Zeed<    eddh«      Zeed<    eddh«      Zeed<    edd¬«       G d„ d«      «       Z ee gee   f   Z!eed<   de defd„Z"de#de#de#dee#   fd„Z$dZ%d d!de&fd"„Z'd d!de&fd#„Z(e"fde d$e!ddfd%„Z)d7d&„Z*d d!d'eddfd(„Z+d'ede&fd)„Z,d'ede&fd*„Z- edd¬«       G d+„ d,«      «       Z.i Z/e0e1e.f   ed-<   d.e1d/d0ddfd1„Z2d'e3d2ee1e3f   d3e1dd4fd5„Z4e"fd.e1d$e!ddfd6„Z5y)8a  
Cost tracking for background interactions.

A create request with ``background=true`` returns ``in_progress`` with no
usage block, and GET polls are deliberately never billed (billing them would
double-charge every poll; the GET response also does not echo ``background``,
so a poll cannot be told apart from a re-fetch of an already-billed
interaction). The create call is therefore the only place that can own
billing: it schedules a poll task that fetches the interaction until it
reaches a terminal status and logs the final usage as a single success event
attributed to the original request.

``requires_action`` is terminal for the interaction it names. The API has no
operation that resumes one: a caller answers a tool request by creating a new
interaction whose ``previous_interaction_id`` points at it, and that new
interaction bills itself. The paused interaction keeps the tokens it already
spent producing the tool request, so it is billed and settled where it stops
rather than polled until the timeout, which would both lose that usage and
hold its budget reservation open for the whole timeout window.

Deleting an interaction makes every subsequent poll fail, which would let a
caller retrieve the completed output themselves and then delete it before the
poll task settles, leaving the work unbilled and the budget reservation
refunded at the poll timeout. ``adelete`` therefore settles any pending poll
for the interaction before dispatching the delete: it fetches the current
state with the create's credentials, bills it if it is terminal with usage,
and releases the reservation otherwise. A settlement gate on the create's
logging object makes the poll task and the delete path mutually exclusive, so
the interaction is billed exactly once no matter who settles first.
é    N)Ú	AwaitableÚCallableÚIteratorÚMapping)Ú	dataclass)ÚTYPE_CHECKINGÚFinalÚ	TypeAlias)Úverbose_logger)Ú9BACKGROUND_INTERACTION_COST_POLL_INITIAL_INTERVAL_SECONDSÚ5BACKGROUND_INTERACTION_COST_POLL_MAX_INTERVAL_SECONDSÚ0BACKGROUND_INTERACTION_COST_POLL_TIMEOUT_SECONDSÚ+BACKGROUND_INTERACTION_COST_POLLING_ENABLED)Ú get_litellm_metadata_from_kwargs)ÚInteractionsAPIResponse©ÚLogging>   ÚfailedÚ	cancelledÚ	completedÚ
incompleteÚbudget_exceededÚrequires_actionÚ_TERMINAL_STATUSESÚin_progressÚqueuedÚ_POLLABLE_STATUSESr   r   Ú_STATUSES_THAT_PRODUCED_OUTPUTT)ÚfrozenÚslotsc                   ó~   — e Zd ZU eed<   eed<   ded<   dZedz  ed<   dZedz  ed<   eZe	ed<   e
Ze	ed	<   eZe	ed
<   y)Ú BackgroundInteractionPollContextÚinteraction_idÚcustom_llm_providerÚLiteLLMLoggingObjÚlogging_objNÚapi_keyÚapi_baseÚinitial_interval_secondsÚmax_interval_secondsÚtimeout_seconds)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__r'   r(   r   r)   Úfloatr   r*   r   r+   © ó    úq/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/interactions/background_cost_polling.pyr"   r"   ;   sP   … àÓØÓØ$Ó$Ø€GˆS�4‰ZÓØ€Hˆc�D‰jÓØ&_Ð˜eÓ_Ø"WÐ˜%ÓWØM€O�UÔMr3   r"   ÚFetchInteractionÚcontextÚreturnc              ƒ   ó˜   K  — ddl m}  |d| j                  | j                  | j                  | j
                  dœddi¤Žƒ d {  –—† S 7 Œ­w)Nr   )Úaget)r#   r$   r'   r(   zno-logTr2   )Úlitellm.interactionsr9   r#   r$   r'   r(   )r6   r9   s     r4   Ú_fetch_interactionr;   J   sX   è ø€ Ý)áð Ø×-Ñ-Ø#×7Ñ7Ø—‘Ø×!Ñ!ñ	ð �dð
ñ÷ ð ð ús   ‚AA
ÁAÁA
ÚinitialÚmaximumÚtimeoutc              #   ó€   K  — d}| }|dkD  r1||z   |k  r(|–— ||z  }t        |dz  |«      }|dkD  r
||z   |k  rŒ&y y y y ­w)Ng        r   é   )Úmin)r<   r=   r>   ÚelapsedÚintervals        r4   Ú_poll_intervalsrD   X   s^   è ø€ Ø€GØ€HØ
�QŠ,˜7 XÑ-°Ò8ØŠØ�8ÑˆÜ�x !‘| WÓ-ˆð �QŠ,˜7 XÑ-°Ô8ˆ,Ð8ˆ,ùs   ‚7>º>Úbackground_interaction_settledr&   r%   c                 óD   — | j                   j                  t        «      du S )NT)Úmodel_call_detailsÚgetÚ_SETTLED_KEY©r&   s    r4   Ú_is_settledrK   d   s   € Ø×)Ñ)×-Ñ-¬lÓ;¸tÐCÐCr3   c                 óB   — t        | «      ryd| j                  t        <   y)zå
    Exactly-once gate between the poll task and the delete-time settlement:
    both run on the same event loop and neither awaits between reading and
    setting the flag, so whichever claims first owns billing or release.
    FT)rK   rG   rI   rJ   s    r4   Ú_claim_settlementrM   h   s"   € ô �;ÔØØ37€K×"Ñ"¤<Ñ0Ør3   Úfetch_interactionc              ƒ   ó´  K  — d }t        | j                  | j                  | j                  ¬«      D ]É  }t	        j
                  |«      ƒ d {  –—†  t        | j                  «      r y 	  || «      ƒ d {  –—† }|j                  }|j                  t        vrŒgt        | j                  «      s y |j                  �!t!        | j                  |¬«      ƒ d {  –—†   y t#        | j                  ¬«      ƒ d {  –—†   y  t        | j                  «      sy |�5|t$        vr-t        j&                  d| j                  | j                  |«       n+t        j(                  d| j                  | j                  «       t#        | j                  ¬«      ƒ d {  –—†  y 7 �ŒH7 �Œ## t        $ r,}t        j                  d| j                  |«       Y d }~�Œ™d }~ww xY w7 Œü7 ŒÞ7 ŒG­w)N)r<   r=   r>   z>Background interaction cost poll for %s failed, will retry: %s©r&   ÚresponserJ   zÐGave up cost polling for background interaction %s after %ss: its last status %r is in neither the pollable nor the terminal set, so this proxy never learned how to settle it and its usage will not be trackedz[Gave up cost polling for background interaction %s after %ss; its usage will not be tracked)rD   r)   r*   r+   ÚasyncioÚsleeprK   r&   Ú	Exceptionr   Údebugr#   Ústatusr   rM   ÚusageÚ_bill_settled_interactionÚ _release_open_budget_reservationr   ÚerrorÚwarning)r6   rN   Úlast_seen_statusrC   rQ   Úes         r4   Ú(poll_and_log_background_interaction_costr^   t   s¶  è ø€ ð $(ÐÜ#Ø×0Ñ0Ø×,Ñ,Ø×'Ñ'ôò ˆô
 �m‰m˜HÓ%×%Ð%Ü�w×*Ñ*Ô+Ùð	Ù.¨wÓ7×7ˆHð $Ÿ?™?ÐØ�?‰?Ô"4Ñ4ØÜ  ×!4Ñ!4Ô5ÙØ�>‰>Ð%Ü+¸×8KÑ8KÐV^Ô_×_Ð_ñ 	ô 3¸w×?RÑ?RÔS×SÐSÙð5ô6 ˜W×0Ñ0Ô1ØØÐ#Ð(8Ô@RÑ(RÜ×Ñð"ð ×"Ñ"Ø×#Ñ#Øõ	
ô 	×ÑØiØ×"Ñ"Ø×#Ñ#ô	
ô
 +°w×7JÑ7JÔ
K×KÑKðO 	&ùð 8úÜò 	Ü× Ñ ØPØ×&Ñ&Øôõ
 ûð	úð `øàSøð& Lús€   ‚A
GÁFÁGÁ)FÁ4FÁ5FÁ9AGÃGÃGÃ5GÃ6BGÆGÆGÆFÆ	GÆ#!G
ÇGÇ
GÇGÇGÇGc              ƒ   óø   K  — t        | j                  ¬«      }|j                  d«      }t        |t        «      syddlm} 	  ||¬«      ƒ d{  –—†  y7 Œ# t        $ r t        j                  d«       Y yw xY w­w)aô  
    The proxy keeps the pre-call budget reservation open for an in-progress
    background interaction so concurrent creates cannot stack past the budget.
    The completion success event reconciles it to the actual cost; when the
    interaction terminates without billable usage (or polling gives up, or it
    is deleted before settling), no such event fires, so whoever claims the
    settlement must release the reservation here or the spend counters stay
    pinned at the estimated cost.
    )ÚkwargsÚuser_api_key_budget_reservationNr   )Úrelease_budget_reservation)Úbudget_reservationzKFailed to release budget reservation for an unbilled background interaction)
r   rG   rH   Ú
isinstanceÚdictÚ/litellm.proxy.spend_tracking.budget_reservationrb   rT   r   Ú	exception)r&   Úmetadatarc   rb   s       r4   rY   rY   ¨   sm   è ø€ ô 0°{×7UÑ7UÔV€HØ!Ÿ™Ð&GÓHÐÜÐ(¬$Ô/ØåZðpÙ(Ð<NÔO×OÒOùÜò pÜ× Ñ Ð!nÖoðpüs;   ‚?A:ÁA ÁAÁA ÁA:ÁA ÁA7Á4A:Á6A7Á7A:rQ   c              ƒ   óŒ   K  — 	 | j                  |¬«      ƒ d{  –—†  y7 Œ# t        $ r t        | ¬«      ƒ d{  –—†7   ‚ w xY w­w)a.  
    Claiming the settlement makes the claimer solely responsible for the
    reservation, and no one retries a claim that is already set. A billing
    failure here must therefore release the reservation on its way out, or it
    stays pinned at the estimated cost until the whole poll times out.
    )ÚresultNrJ   )Ú+async_log_background_interaction_completionrT   rY   rP   s     r4   rX   rX   ¿   sA   è ø€ ðØ×EÑEÈXÐEÓV×VÒVùÜò Ü.¸;ÔG×GÑGØðüs.   ‚A„! ™š! žAŸ! ¡A¹<ºAÁAc                 óT   — | j                   t        v xr t        | j                  «      S )að  
    The single gate deciding whether a create's response gets a poll task.
    The proxy's success callback defers releasing the budget reservation for
    exactly these responses, on the promise that a poll task will settle them,
    so a response one site accepts and the other refuses strands its
    reservation on the spend counters with nothing left to reconcile it.

    ``queued`` belongs here alongside ``in_progress``. It is the API's
    not-started-yet state, so it reaches a terminal status the same way and
    needs polling for the same reason: nothing else in the proxy ever bills a
    create that came back without usage, so a status missing from both this
    set and ``_TERMINAL_STATUSES`` is billed nowhere and alerts nobody.
    )rV   r   ÚboolÚid©rQ   s    r4   Ú"is_pollable_background_interactionrp   Í   s"   € ð �?‰?Ô0Ð0ÒF´T¸(¿+¹+Ó5FÐFr3   c                 ó&   — | j                   t        vS )aQ  
    Whether a response arriving with no usage block is a normal outcome rather
    than lost billing data. An interaction that is still running, or that
    stopped at ``failed``, ``cancelled``, ``incomplete`` or ``budget_exceeded``,
    has nothing to charge for and should not raise a cost-tracking alarm.

    ``completed`` and ``requires_action`` both mean the model produced output,
    so a usage block is always expected with them. If one arrives without it
    the charge for real work has been lost, which is precisely what the
    proxy's cost-tracking alert exists to surface.
    )rV   r   ro   s    r4   Úmissing_usage_is_expectedrr   Þ   s   € ð �?‰?Ô"@Ð@Ð@r3   c                   ó"   — e Zd ZU ded<   eed<   y)Ú_ActiveBackgroundPollúasyncio.Task[None]Útaskr6   N)r,   r-   r.   r0   r"   r2   r3   r4   rt   rt   í   s   … à
ÓØ-Ô-r3   rt   Ú_ACTIVE_POLLSr#   rv   ru   c                 ó`   — t         j                  | «      }|�|j                  |u rt         | = y y y ©N)rw   rH   rv   )r#   rv   Úentrys      r4   Ú_discard_pollr{   ö   s3   € Ü×Ñ˜nÓ-€EØÐ˜UŸZ™Z¨4Ñ/Ü˜.Ñ)ð 0Ðr3   Úcreate_kwargsr$   zasyncio.Task[None] | Nonec           
      óR  — ddl m} t        sy t        | t        «      sy t        | «      sy |j                  d«      }t        ||«      sy 	 t        j                  «        |j                  d«      }|j                  d«      }t        | j                  ||t        |t        «      r|nd t        |t        «      r|nd ¬«      }t        j                  t        |«      «      }t        ||¬«      t         |j"                  <   |j%                  |j"                  fd„«       |S # t        $ r Y y w xY w)	Nr   r   Úlitellm_logging_objr'   r(   )r#   r$   r&   r'   r(   )rv   r6   c                 ó   — t        || «      S ry   )r{   )Úfinishedr#   s     r4   ú<lambda>zDmaybe_schedule_background_interaction_cost_polling.<locals>.<lambda>  s   € ÄÈnÐ^fÓ@g€ r3   )Ú*litellm.litellm_core_utils.litellm_loggingr   r   rd   r   rp   rH   rR   Úget_running_loopÚRuntimeErrorr"   rn   r/   Úcreate_taskr^   rt   rw   r#   Úadd_done_callback)	rQ   r|   r$   r   r&   r'   r(   r6   rv   s	            r4   Ú2maybe_schedule_background_interaction_cost_pollingr‡   ü   s  € õ
 Cå6ØÜ�hÔ 7Ô8ØÜ-¨hÔ7ØØ×#Ñ#Ð$9Ó:€KÜ�k 7Ô+ØðÜ× Ñ Ô"ð ×Ñ 	Ó*€GØ× Ñ  Ó,€HÜ.Ø—{‘{Ø/ØÜ% g¬sÔ3‘¸Ü'¨´#Ô6‘¸Dô€Gô ×ÑÔGÈÓPÓQ€DÜ,AÀtÐU\Ô,]„M�'×(Ñ(Ñ)Ø×ÑØ(/×(>Ñ(>Ògôð €Køô! ò Ùðús   Á
D Ä	D&Ä%D&c              ƒ   ó(  K  — t         j                  | «      }|€y |j                  }	  ||«      ƒ d {  –—† }t        |j                  «      sy |j                  t        v r,|j                  � t        |j                  |¬«      ƒ d {  –—†  y t        |j                  ¬«      ƒ d {  –—†  y 7 Œw# t        $ rU}t	        j
                  d| |«       t        |j                  «      rt        |j                  ¬«      ƒ d {  –—†7   Y d }~y d }~ww xY w7 Œ‡7 Œj­w)NzVCould not fetch background interaction %s before delete, releasing its reservation: %srJ   rP   )rw   rH   r6   rT   r   rU   rM   r&   rY   rV   r   rW   rX   )r#   rN   rz   r6   rQ   r]   s         r4   Ú1maybe_settle_background_interaction_before_deleter‰   !  sï   è ø€ ô ×Ñ˜nÓ-€EØ€}ØØ�m‰m€Gð
Ù*¨7Ó3×3ˆô ˜W×0Ñ0Ô1ØØ‡�Ô,Ñ,°·±Ð1KÜ'°G×4GÑ4GÐRZÔ[×[Ð[ØÜ
*°w×7JÑ7JÔ
K×KÑKð 4ùÜò Ü×ÑØdØØô	
ô
 ˜W×0Ñ0Ô1Ü2¸w×?RÑ?RÔS×SÑSÜûðúð 	\øàKúsi   ‚%D¨B- ³B+´B- ¸ADÂDÂDÂ%DÂ&DÂ+B- Â-	DÂ6ADÃ;C>Ã<DÄDÄDÄDÄD)r&   r%   r7   N)6Ú__doc__rR   Úcollections.abcr   r   r   r   Údataclassesr   Útypingr   r	   r
   Úlitellm._loggingr   Úlitellm.constantsr   r   r   r   Ú'litellm.litellm_core_utils.core_helpersr   Úlitellm.types.interactionsr   r‚   r   r%   Ú	frozensetr   r0   r   r   r"   r5   r;   r1   rD   rI   rm   rK   rM   r^   rY   rX   rp   rr   rt   rw   re   r/   r{   Úobjectr‡   r‰   r2   r3   r4   ú<module>r”      sT  ðòó> ß BÓ BÝ !ß 2Ñ 2å +÷ó õ UÝ >áÝWá%Ú\óÐ �Eó ñ & }°hÐ&?Ó@Ð �EÓ @á(1°;Ð@QÐ2RÓ(SÐ  Ó Sñ �$˜dÔ#÷Nð Nó $ðNð 'Ð(HÐ'IÈ9ÐUlÑKmÐ'mÑnÐ �)Ó nðÐ&Fð ÐKbó ð.˜Uð .¨Uð .¸Uð .ÀxÐPUÁó .ð 0€ðDÐ0ð D°Tó Dð	Ð#6ð 	¸4ó 	ð +=ñ1LØ-ð1Là'ð1Lð 
ó1Lóhpð.Ð1Dð ÐPgð Ðlpó ðGÐ1Hð GÈTó Gð"AÐ(?ð AÀDó Añ �$˜dÔ#÷.ð .ó $ð.ð
 35€ˆt�CÐ.Ð.Ñ/Ó 4ð* #ð *Ð-Að *Àdó *ð"Øð"à˜3 ˜;Ñ'ð"ð ð"ð !ó	"ðN +=ñLØðLà'ðLð 
ôLr3   