ó
    À‘´jI  ã                  óV  • S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSK	J
r
JrJrJrJrJrJrJrJr  SSKrSSKJr  SSKJrJr  SS	KJrJrJrJrJrJrJ r J!r!  SS
K"J#r#  SSK$J%r%  SSK&J'r'J(r(  SSK)J*r*  \
(       a  SSK+J,r,   " S S\5      r-Sr.Sr/Sr0Sr1Sr2Sr3\" \.S9r4\" \/\0\1\2\3/S9r5Sr6 " S S\5      r7 " S S\5      r8 " S S\5      r9\" S S!9S/S" j5       r:S0S# jr;\" S$5      r< " S% S&5      r=          S1S' jr>S2S( jr?S3S) jr@S4S* jrA        S5S+ jrBS6S, jrCS7S- jrDS7S. jrEg)8aÔ  Jev ranking of retrieved chunks for the playground's answer path.

Ownership. This module decides which of a question's retrieved chunks the
answer model reads when the playground's ranker setting is `jev`. `selection`
holds the Haiku equivalent, and `retrieval.retrieve` chooses between them and
composes the final context. Both satisfy `ChunkRanker`: the question and the
candidates in, indices into the candidates out, most relevant first.

How it ranks. Jev, TypeSafe's scoring model, does not read the candidates as
one prompt. Every page and every chunk is judged alone, in its own request,
so the ranker can afford the whole fused list rather than a window of it.
Two passes. Each distinct page in the candidate list is asked whether it has
material relevant to the question, and a page answered no is dropped with
every candidate on it. Each candidate on a page that passed is then graded
on a four-level rubric, and `Ranking.order` keeps the ones at or above the
configured cut, highest first. Nothing is added back from fused order when
fewer clear the cut: anything added that way is a chunk Jev graded as
unrelated or same-topic, or one on a page Jev rejected.

What leaves the host. The question, each page's text and each chunk's text
are sent to TypeSafe's API, one text per request. TypeSafe states it does not
train on requests; zero data retention is an enterprise option not yet taken.

Failures. The SDK retries 429, 5xx, connection and timeout errors itself.
After each pass, the calls that still failed are run once more. A page that
fails twice counts as relevant, so its chunks are still graded. A chunk that
fails twice goes after the graded ranking in fused order. Every failed page
or chunk is named in the log and the trace, because it may be the one that
holds the answer. `rank` raises when every call in a pass fails, and on any
error that is not a `TypeSafeError`, such as a missing TYPESAFE_API_KEY or a
failed page-text query. `retrieve` then falls back to fused order.
é    )ÚannotationsN)ÚCounter)Ú	lru_cache)	ÚTYPE_CHECKINGÚAnyÚ	AwaitableÚCallableÚDictÚListÚOptionalÚProtocolÚTypeVar)Úlogger)Ú	BaseModelÚField)ÚAsyncTypeSafeClientÚNoulÚ
NoulAnswerÚRetryPolicyÚScoreÚScoreAnswerÚTypeSafeAPIErrorÚTypeSafeError)Úusage_metadata_from)Údb)Úrun_metadataÚtracer)Úget_settings)ÚRetrievedChunkc                  ó"   • \ rS rSrSrSS jrSrg)ÚChunkRankeréK   zVThe question and a candidate list in; indices into that list out, most relevant first.c              ƒ  ó   #   • g 7f©N© )ÚselfÚquestionÚcandss      Ú6/home/mande/repo/quber/src/quber/playground/ranking.pyÚ__call__ÚChunkRanker.__call__N   s   é € ÐY\ùs   ‚r%   N©r'   Ústrr(   úList['RetrievedChunk']Úreturnú	List[int])Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r*   Ú__static_attributes__r%   ó    r)   r!   r!   K   s   † Ù`ç\r7   r!   zØDoes this page have material relevant to the query? Yes when the page discusses the metric, line item, or statement the query asks about. No when the page is about other subjects and nothing on it bears on the query.z(How does this chunk relate to the query?zIThe chunk is about a different subject; nothing in it bears on the query.zpThe chunk is on the same topic as the query but gives neither the asked-for item nor anything that qualifies it.z~The chunk supports the asked-for item: a definition, a footnote, a component, a reconciliation, or a comparison period for it.zXThe chunk states the asked-for item directly, for the entity and period the query names.)Úinstructions)r8   Úcriteriaç      à?c                  óJ   • \ rS rSr% SrS\S'   S\S'   SrS\S	'   SrS
\S'   Srg)Ú	PageScoreé~   z7One page's verdict. `page` is the stored 0-based index.ÚintÚpageÚboolÚrelevantNúOptional[float]Ú
confidenceúOptional[str]Úerrorr%   )	r1   r2   r3   r4   r5   Ú__annotations__rC   rE   r6   r%   r7   r)   r<   r<   ~   s#   ‡ ÙAà
ƒIØƒNà"&€J�Ó&Ø€Eˆ=Ör7   r<   c                  ób   • \ rS rSr% SrS\S'   S\S'   S\S'   SrS	\S
'   SrS\S'   SrS\S'   Sr	g)Ú
ChunkScoreéˆ   zEOne candidate's grade. `index` is its position in the candidate list.r>   Úindexr-   Úchunk_idr?   NzOptional[int]ÚgraderB   ÚscorerD   rE   r%   )
r1   r2   r3   r4   r5   rF   rL   rM   rE   r6   r%   r7   r)   rH   rH   ˆ   s4   ‡ ÙOàƒJØƒMØ
ƒIà€Eˆ=Óð "€Eˆ?Ó!Ø€Eˆ=Ör7   rH   c                  ó–   • \ rS rSr% SrS\S'   S\S'   S\S'   S	rS
\S'   SrS\S'   SrS\S'   \	" \
S9rS\S'   SS jrSS jrSS jrSrg	)ÚRankingé—   z1Everything both passes returned for one question.zList[PageScore]ÚpageszList[ChunkScore]ÚscoresÚfloatÚ	grade_cutNrD   Úmodelç        Úsecondsr   r>   Úinput_tokens)Údefault_factoryzDict[str, int]Úfailuresc                óž  • U R                    Vs/ s H/  oR                  c  M  UR                  U R                  :¼  d  M-  UPM1     nnUR                  S SS9  U R                    Vs/ s H  oR                  c  M  UPM     nnU Vs/ s H  oR
                  PM     snU Vs/ s H  oR
                  PM     sn-   $ s  snf s  snf s  snf s  snf )zsCandidate indices at or above the cut, highest score first, then the
chunks whose calls failed, in candidate order.c                ó,   • U R                   =(       d    S$ ©NrV   ©rM   )Úcs    r)   Ú<lambda>ÚRanking.order.<locals>.<lambda>ª   s   €  !§'¡'§.¨S .r7   T©ÚkeyÚreverse)rR   rM   rT   ÚsortrE   rJ   )r&   r_   ÚgradedÚfaileds       r)   ÚorderÚRanking.order¦   sš   € ð "Ÿ[š[Ó^š[˜¯G©G“!ÀAÇGÁGÈtÏ~É~ÑD]—!™[ˆÐ^Ø�‰Ñ0¸$ˆÑ?Ø!Ÿ[š[Ó@š[˜¯G©G—!™[ˆÐ@Ù!'Ó(¢˜A—”¡Ñ(¹VÓ+DºV¸¯G¬G¹VÑ+DÑDÐDùò _ùâ@ùÚ(ùÒ+Ds'   �B;£B;¿B;Á&C Á:C ÂCÂ!C
c                óB   ^ • [        U 4S jT R                   5       5      $ )Nc              3  ó|   >#   • U  H1  oR                   c  M  UR                   TR                  :¼  d  M-  Sv •  M3     g 7f)Né   )rM   rT   )Ú.0r_   r&   s     €r)   Ú	<genexpr>Ú"Ranking.cleared.<locals>.<genexpr>¯   s+   øé € Ð_šk˜¯W©W“1ÀQÇWÁWÐPT×P^ÑP^ÑE^—1‘1škùs   ƒ<—<³	<)ÚsumrR   ©r&   s   `r)   ÚclearedÚRanking.cleared®   s   ø€ ÜÔ_˜dŸkškÓ_Ó_Ð_r7   c                ó~   • U R                    Vs/ s H!  oR                  (       d  M  UR                  PM#     sn$ s  snf r$   )rQ   rA   r?   )r&   Úps     r)   Ú
kept_pagesÚRanking.kept_pages±   s(   € Ø $§
¢
Ó9¢
˜1¯j­j“�—”¡
Ñ9Ð9ùÒ9s   �:§:r%   )r/   r0   )r/   r>   )r1   r2   r3   r4   r5   rF   rU   rW   rX   r   ÚdictrZ   rh   rr   rv   r6   r%   r7   r)   rO   rO   —   sW   ‡ Ù;àÓàÓØÓØ€Eˆ=ÓØ€GˆUÓØ€L�#Óñ  %°TÑ:€HˆnÓ:ôEô`÷:r7   rO   rl   )Úmaxsizec                 ó  • [        5       R                  n U R                  (       d  [        S5      e[        R
                  " U R                  [        R                  " SSS9S9n[        U R                  [        U R                  S9US9$ )as  The one SDK client both passes share, so every call reuses one
connection pool. The pool is unbounded: a batch of questions, each with
`concurrency` calls in flight, would otherwise queue on httpx's default
of 100 connections and reopen the ones past its keep-alive cap of 20 on
every call. The per-question semaphore and the batch's question cap are
what bound the load.z5TYPESAFE_API_KEY is not set; the jev ranker needs it.N)Úmax_connectionsÚmax_keepalive_connections)ÚtimeoutÚlimits)Úmax_retries)Úapi_keyÚretryÚhttp_client)r   Útypesafer€   ÚRuntimeErrorÚhttpx2ÚAsyncClientÚtimeout_secondsÚLimitsr   r   r   )ÚtsÚhttps     r)   Úclientr‹   µ   so   € ô 
‹×	 Ñ	 €BØ�:�:ÜÐRÓSÐSÜ×ÒØ×"Ñ"¬6¯=ª=ÈÐimÑ+nñ€Dô Ø—
‘
¤+¸"¿.¹.Ñ"IÐW[ñð r7   c              ƒ  ó‚  #   • [        U  Vs1 s H  oR                  iM     sn5      nU  Vs/ s H  oR                  PM     nnSnU Vs0 s H  oU/ _M     nn[        R                  " 5        ISh  v•N nUR                  XCUS.5      I Sh  v•N R                  5       I Sh  v•N  H  u  p‰Xh   R                  U	5        M     SSS5      ISh  v•N   UR                  5        VV
s0 s H  u  pZUSR                  U
5      _M     sn
n$ s  snf s  snf s  snf  N¦ NŒ Nx NN! , ISh  v•N  (       d  f       Nc= fs  sn
nf 7f)a  The text of each distinct candidate page: its chunks that are not line
records, joined in stored order.

Candidates carry no document key, so the pages are read from the
document that holds the most of the candidates' chunk ids. Those ids are
docling refs and positional names such as `#/texts/12`, `#/tables/3` and
`t3-line-5`, unique only within a document. Another document that holds
every candidate id ties with the right one, and the query does not break
the tie, so the pages can come from the wrong document.
aŸ  
        WITH doc AS (
            SELECT document_id FROM ade_playground.chunks
            WHERE chunk_id = ANY(%(ids)s)
            GROUP BY document_id ORDER BY count(*) DESC LIMIT 1
        )
        SELECT k.page, k.content
        FROM ade_playground.chunks k JOIN doc ON doc.document_id = k.document_id
        WHERE k.page = ANY(%(pages)s) AND k.chunk_type <> 'line_item'
        ORDER BY k.page, k.id
    N)ÚidsrQ   z

)
Úsortedr?   rK   r   Úconnect_asyncÚexecuteÚfetchallÚappendÚitemsÚjoin)r(   r_   rQ   r�   Úsqlru   ÚtextsÚconnr?   ÚcontentÚpartss              r)   Ú
page_textsrš   È   s  é € ô ¡EÓ*¢E˜q—F”F¡EÑ*Ó+€EÙ$Ó
%šu˜!�:Œ:™u€CÐ
%ð
€Cñ 38Ó"8²%¨Q b¢5±%€EÐ"8Ü×Ò×!Ô! TØ*.¯,©,°sÐRWÑ<XÓ*Y×$Y×#cÑ#cÓ#e×eÒe‰MˆDØ‰K×Ñ˜wÖ'ñ f÷ "×!ð 38·+±+´-Ô@²-¡h aˆAˆv�{‰{˜5Ó!Ò!±-Ò@Ð@ùò# +ùÚ
%ùò #9Ù!Ù$YÑe÷ "×!×!Ð!üó Aùs˜   ‚
D?ŒD¡D?¬DÁD?Á	DÁD?Á0DÁ1D?Á4DÂDÂDÂ"DÂ# DÃD?ÃDÃD?Ã&D9ÄD?ÄDÄDÄD?ÄD6Ä%D(Ä&D6Ä2D?ÚTc                  ó6   • \ rS rSrSrSS jrS	S jrS
S jrSrg)Ú_Tallyéê   z‚What every call adds up to: tokens, the resolved model id, failures.
Shaped so `usage_metadata_from` can read it like a run usage.c                óL   • SU l         SU l        S U l        [        5       U l        g ©Nr   )rX   Úoutput_tokensrU   r   rZ   rq   s    r)   Ú__init__Ú_Tally.__init__î   s"   € ØˆÔØˆÔØ$(ˆŒ
Ü&-£iˆ�r7   c                ó  • U =R                   UR                  R                   =(       d    S-  sl         U =R                  UR                  R                  =(       d    S-  sl        UR                  =(       d    U R                  U l        g r    )rX   Úusager¡   rU   )r&   Úresponses     r)   ÚrecordÚ_Tally.recordô   sV   € Ø×Ò˜XŸ^™^×8Ñ8×=¸AÑ=ÕØ×Ò˜hŸn™n×:Ñ:×?¸aÑ?ÕØ—^‘^×1 t§z¡zˆ�
r7   c                ó¼   • [        U[        5      (       a  [        UR                  5      O[	        U5      R
                  nU R                  U==   S-  ss'   U SU 3$ )Nrl   ú: )Ú
isinstancer   r-   ÚstatusÚtyper1   rZ   )r&   Úexcrc   s      r)   rg   Ú_Tally.failedù   sL   € Ü!+¨CÔ1A×!BÑ!BŒc�#—*‘*ŒoÌÈSË	×HZÑHZˆØ�‰�cÓ˜aÑÓØ��b˜˜ˆÐr7   )rZ   rX   rU   r¡   N)r/   ÚNone)r¦   r   r/   r°   )r®   Ú	Exceptionr/   r-   )	r1   r2   r3   r4   r5   r¢   r§   rg   r6   r%   r7   r)   r�   r�   ê   s   † ñEô0ô2÷
r7   r�   c              ƒ  ó¨  ^ ^^	^
#   • [         R                  " U5      m
SUU
4S jjm	[        [         R                  " U	4S jT  5       6 I Sh  v•N 5      n[	        U5       VVs/ s H  u  pVU" U5      (       d  M  UPM     nnnU(       a=  [         R                  " U	U 4S jU 5       6 I Sh  v•N n[        XxSS9 H	  u  pVXdU'   M     U$  N|s  snnf  N%7f)z„Run `call` over `items` at most `concurrency` at a time, then once more
over the items whose result `failed`. Results in item order.c              “  ó¤   >#   • T IS h  v•N   T" U 5      I S h  v•N sS S S 5      IS h  v•N   $  N% N N	! , IS h  v•N  (       d  f       g = f7fr$   r%   )ÚitemÚcallÚsems    €€r)   ÚguardedÚ_twice.<locals>.guarded  s,   øé € ß’3Ù˜d›×#÷ —3“3Ù#÷ —3—3�3üsE   ƒAŠ0‹AŽ6š2›6žAª4«A²6´A¶A¼?½AÁ	Ac              3  ó4   >#   • U  H  nT" U5      v •  M     g 7fr$   r%   )rm   Úir·   s     €r)   rn   Ú_twice.<locals>.<genexpr>
  s   øé € Ð)Dºe¸©'°!¯*¨*ºeùs   ƒNc              3  ó:   >#   • U  H  nT" TU   5      v •  M     g 7fr$   r%   )rm   Únr·   r“   s     €€r)   rn   r»     s   øé € Ð&HÂ%¸Q¡w¨u°Q©x×'8Ð'8Â%ùs   ƒT)Ústrict)r´   r›   r/   r   )ÚasyncioÚ	SemaphoreÚlistÚgatherÚ	enumerateÚzip)r“   rµ   rg   ÚconcurrencyÚresultsr½   Úrr�   Úagainr·   r¶   s   ``       @@r)   Ú_twicerÉ   ÿ   s¨   ûé € ô
 ×
Ò
˜KÓ
(€C÷$ð $ô œŸšÔ)D¹eÓ)DÐE×EÓF€GÜ$ WÔ-Ô;Ò-‘4�1±¸·�QÑ-€EÑ;ÞÜ—n’nÕ&HÁ%Ó&HÐI×IˆÜ˜¨TÔ2‰DˆAØ�A‹Jñ 3à€Nñ FùÛ;áIùs6   †ACÁCÁCÁ"C
Á9C
Á?+CÂ*CÂ+CÃ
Cc            	     ól   • SR                  S [        [        [        [        [
        45       5       5      $ )NÚ
c              3  ó4   #   • U  H  u  pU S U 3v •  M     g7f)rª   Nr%   )rm   r½   Úds      r)   rn   Ú_levels.<locals>.<genexpr>  s    é € ð Ú l™˜ˆ1ˆ#ˆR�ˆs�Ò lùs   ‚)r”   rÃ   ÚLEVEL_UNRELATEDÚLEVEL_SAME_TOPICÚLEVEL_SUPPORTSÚLEVEL_STATESr%   r7   r)   Ú_levelsrÓ     s0   € Ø�9‰9ñ Ü )¬?Ô<LÌnÔ^jÐ*kÔ lóó ð r7   c                ó¤   • 0 UE[        U 5      [        U R                  5      [        [        R
                  " 5       U-
  S5      U R                  S.E$ )z:The fields every traced pass records, plus the pass's own.é   )Úusage_metadatarZ   rW   rU   )r   rx   rZ   ÚroundÚtimeÚperf_counterrU   )ÚtallyÚstartedÚfieldss      r)   Ú_run_outputsrÝ     sL   € ðØ
ðä-¨eÓ4Ü˜Ÿ™Ó(Üœ×*Ò*Ó,¨wÑ6¸Ó:Ø—‘òð r7   c              ƒ  óŠ  ^ ^
^^#   • [        5       R                  m[        5       m
[        U5      I Sh  v•N mS[        S.ST S./[        T5       Vs/ s H  o"S-   PM	     snS.nSU U
UU4S jjn[        R                  " 5       n[        5       R                  S	UTR                  [        5       S
9 ISh  v•N n[        [        T5      US TR                  5      I Sh  v•N nU Vs/ s H'  nTR                  UR                  5      (       d  M%  UPM)     nnU(       a8  [!        S U 5       5      (       a!  [#        S[%        T
R&                  5       35      e[        US S9n	[)        T
US[+        U Vs/ s H$  o"R,                  (       d  M  UR                  S-   PM&     sn5      S./U	 Vs/ s H&  n0 UR/                  5       ESUR                  S-   0EPM(     sn[1        S U 5       5      S9Ul        SSS5      ISh  v•N   UT
4$  GNÔs  snf  GNZ GN3s  snf s  snf s  snf  N%! , ISh  v•N  (       d  f       WT
4$ = f7f)z€Pass 1: one yes/no call per distinct candidate page. One traced run
named `page_rank`, with every verdict, relevant pages first.NÚsystem©Úroler˜   Úuserrl   )ÚmessagesrQ   r?   c           
   “  ó(  >#   • TR                  U S5      nU(       d
  [        U SS9$  [        5       R                  ST SU S-    SU 3S[        0TR
                  S	9I S h  v•N nTR                  U5        UR                  S   n[        U[        5      (       d   e[        U UR                  [        :¬  [        [        UR                  [        -
  5      S-  S5      S9$  N~! [         a$  n[        U STR                  U5      S
9s S nA$ S nAff = f7f)NÚ T)r?   rA   úQUERY: z

PAGE rl   z:
rA   ©rU   )r?   rA   rE   rÕ   é   )r?   rA   rC   )Úgetr<   r‹   Ú
system_oneÚPAGErU   r   rg   r§   Úanswersr«   r   ÚnoulÚPAGE_THRESHOLDr×   Úabs)	r?   Útextr¦   r®   Úanswerr'   rÚ   r–   r‰   s	        €€€€r)   ÚjudgeÚjudge_pages.<locals>.judge/  s  øé € Ø�y‰y˜˜rÓ"ˆÞÜ $°Ñ6Ð6ð	PÜ#›X×0Ñ0Ø˜(˜ 9¨T°A©X¨J°c¸$¸Ð@À:ÌtÐBTÐ\^×\dÑ\dð 1ð ÷ ˆHð
 	�‰�XÔØ×!Ñ! *Ñ-ˆÜ˜&¤*×-Ñ-Ð-Ð-ô ØØ—[‘[¤NÑ2ÜœS §¡¬~Ñ!=Ó>ÀÑBÀAÓFñ
ð 	
ñøô ó 	PÜ $°¸U¿\¹\È#Ó=NÑOÕOûð	PüsG   ƒ$D¨8C! Á CÁ!C! Á%A:DÃC! Ã!
DÃ+D
ÄDÄDÄ
DÄDÚ	page_rank©rU   Úextra_metadatac                ó   • U R                   S L$ r$   ©rE   ©ru   s    r)   r`   Újudge_pages.<locals>.<lambda>G  s   € ¸Q¿W¹WÈDÑ=Pr7   c              3  ó<   #   • U  H  oR                   S Lv •  M     g 7fr$   rø   ©rm   ru   s     r)   rn   Újudge_pages.<locals>.<genexpr>I  ó   é € Ð>²v°!Ÿ'™'¨Õ-²vùó   ‚zevery page call failed: c                ó<   • U R                   (       + U R                  4$ r$   )rA   r?   rù   s    r)   r`   rú   K  s   € °1·:±:¬~¸q¿v¹vÑ.Fr7   )rc   Ú	assistantc              3  óJ   #   • U  H  oR                   (       d  M  S v •  M     g7f)rl   N)rA   rü   s     r)   rn   rý   Q  s   é € Ð4¢˜1¯­—Q‘Q¢ùs   ‚#š	#)rã   rQ   Úkept)r?   r>   r/   r<   )r   rƒ   r�   rš   ÚPAGE_QUESTIONrŽ   rØ   rÙ   r   Úllm_runrU   r   rÉ   rÅ   ré   r?   Úallr„   rx   rZ   rÝ   r-   rA   Ú
model_dumprp   Úoutputs)r'   r(   ru   Úinputsrò   rÛ   ÚrunrQ   ÚjudgedÚorderedrÚ   r–   r‰   s   `         @@@r)   Újudge_pagesr  $  sç  ûé € ô 
‹×	 Ñ	 €BÜ‹H€EÜ˜UÓ#×#€Eà&´=ÑAÈFÐ_gÑChÐiÜ!'¨¤Ó/¢˜A�a”%¡Ñ/ñ€F÷

ò 
ô, ×ÒÓ!€GÜ‹x×Ñ ¨V¸2¿8¹8ÔT`ÓTbÐ×cÑcÐgjÜœV E›]¨EÑ3PÐRT×R`ÑR`Óa×aˆÙ"Ó8šU˜ e§i¡i°·±×&7—!™UˆÐ8Þ”cÑ>±vÓ>×>Ñ>ÜÐ!9¼$¸u¿~¹~Ó:NÐ9OÐPÓQÐQÜ˜Ñ$FÑGˆÜ"ØØØ*´sÑPUÓ;dÒPUÈ1×YcÕYc»J¸A¿F¹FÀQ¼JÑPUÑ;dÓ7eÑfÐgÙCJÓKÂ7¸aÐ9�a—l‘l“nÐ9 f¨a¯f©f°q©jÔ9Á7ÑKÜÑ4¡Ó4Ó4ñ
ˆŒ÷ d×cð �%ˆ<ÐòU $ùò 0ò4 dÚaùÚ8ùò <eùÚK÷ d×c×cð �%ˆ<Ðüs­   †-I³H´IÁH
Á AIÂ5HÂ6IÂ9&H&ÃHÃ H&Ã($HÄHÄAH&Å3HÆHÆH&Æ+-HÇH&Ç3IÇ>H$Ç?	IÈ
IÈH&ÈH&È$IÈ&I È,H/È-I È9
Ic              ƒ  óB  ^ ^^#   • [        5       R                  m[        5       m[        U5       VVs/ s H  u  p4UR                  U;   d  M  X44PM     nnnS[
         S[        5        3S.ST S./U VVs/ s H  u  pdUR                  PM     snnS.nSU UU4S jjn[        R                  " 5       n	[        5       R                  SUTR                  [        5       S9 IS	h  v•N n
[        XXS
 TR                  5      I S	h  v•N nU(       a8  [!        S U 5       5      (       a!  [#        S[%        TR&                  5       35      e[)        S U 5       S SS9nU Vs/ s H  oÝR*                  c  M  UPM     nnU Vs/ s H)  oÝR,                  =(       d    STR.                  :¼  d  M'  UPM+     nn[1        TU	S[3        U Vs/ s H  oÝR                  PM     sn5      S./XÎ-    Vs/ s H&  n0 UR5                  5       ESUR                  S-   0EPM(     snTR.                  [7        U5      [7        U5      [7        U5      -
  S9U
l        S	S	S	5      IS	h  v•N   UT4$ s  snnf s  snnf  GN„ GNgs  snf s  snf s  snf s  snf  N.! , IS	h  v•N  (       d  f       WT4$ = f7f)zŠPass 2: one rubric call per candidate on a kept page. One traced run
named `chunk_rank`, with every score, best first, failed chunks last.rß   rË   rà   râ   )rã   Ú	chunk_idsc              “  óœ  >#   • U u  pST SUR                   S-    SUR                   SUR                   3n [        5       R	                  US[
        0T	R                  S9I S h  v•N nTR                  U5        UR                  S   n[        U[        5      (       d   e[        UUR                  UR                   [        [!        UR"                  S	-   5      [%        [
        R&                  5      S-
  5      UR"                  S
9$  N ! [         a8  n[        XR                  UR                   TR                  U5      S9s S nA$ S nAff = f7f)Nræ   z

CHUNK (page rl   z, z):
rL   rç   )rJ   rK   r?   rE   r:   )rJ   rK   r?   rL   rM   )r?   Ú
chunk_typer˜   r‹   rê   ÚCHUNKrU   r   rH   rK   rg   r§   rì   r«   r   Úminr>   rM   Úlenr9   )
r´   rº   r_   Úpromptr¦   r®   rñ   r'   rÚ   r‰   s
          €€€r)   rL   Úgrade_chunks.<locals>.gradef  s#  øé € Ø‰ˆØ˜8˜*Ð$4°Q·V±V¸a±Z°LÀÀ1Ç<Á<À.ÐPTÐUV×U^ÑU^ÐT_Ð`ˆð	bÜ#›X×0Ñ0°¸'Ä5Ð9IÐQS×QYÑQYÐ0ÐZ×ZˆHð 	�‰�XÔØ×!Ñ! 'Ñ*ˆÜ˜&¤+×.Ñ.Ð.Ð.ÜØØ—Z‘ZØ—‘Ü”c˜&Ÿ,™,¨Ñ,Ó-¬s´5·>±>Ó/BÀQÑ/FÓGØ—,‘,ñ
ð 	
ñ [øÜó 	bÜ A·
±
ÀÇÁÈuÏ|É|Ð\_ÓO`ÑaÕaûð	büsG   ƒ4E¸,D Á$DÁ%D Á)BEÄD Ä
E	Ä-EÄ>E	Ä?EÅE	Å	EÚ
chunk_rankrõ   Nc                ó   • U R                   S L$ r$   rø   ©Úss    r)   r`   Úgrade_chunks.<locals>.<lambda>z  s   € °a·g±gÀTÑ6Ir7   c              3  ó<   #   • U  H  oR                   S Lv •  M     g 7fr$   rø   ©rm   r  s     r)   rn   Úgrade_chunks.<locals>.<genexpr>{  rþ   rÿ   zevery chunk call failed: c              3  óB   #   • U  H  oR                   b  M  Uv •  M     g 7fr$   rø   r  s     r)   rn   r  }  s   é € Ð>¢F˜q¯g©gŸ™¢Fùs   ‚–	c                ó,   • U R                   =(       d    S$ r]   r^   r  s    r)   r`   r  }  s   € ÈaÏgÉgÏnÐY\Ènr7   Trb   rV   r  r?   rl   )rã   rR   rT   rr   Ú	below_cut)r´   ztuple[int, 'RetrievedChunk']r/   rH   )r   rƒ   r�   rÃ   r?   ÚCHUNK_QUESTIONrÓ   rK   rØ   rÙ   r   r  rU   r   rÉ   rÅ   r  r„   rx   rZ   rŽ   rE   rM   rT   rÝ   r-   r  r  r  )r'   r(   r  rº   r_   r“   Ú_r	  rL   rÛ   r
  rR   rf   r  rg   rr   rÚ   r‰   s   `               @@r)   Úgrade_chunksr$  V  s=  úé € ô
 
‹×	 Ñ	 €BÜ‹H€EÜ )¨%Ô 0ÔCÒ 0™˜°A·F±F¸d±N‹Vˆa‹VÑ 0€EÑCð ¬^Ð,<¸B¼w»y¸kÐ*JÑKØ¨Ñ1ð
ñ .3Ô3ªU¡T Q�a—j”j©UÒ3ñ€F÷
ñ 
ô$ ×ÒÓ!€GÜ‹x×Ñ ¨f¸B¿H¹HÔUaÓUcÐ×dÑdÐhkÜ˜eÑ,IÈ2Ï>É>ÓZ×ZˆÞ”cÑ>±vÓ>×>Ñ>ÜÐ!:¼4ÀÇÁÓ;OÐ:PÐQÓRÐRÜÑ>¡FÓ>ÑD\ÐfjÑkˆÙ#Ó;šV˜§w¡w—!™VˆÐ;Ù$ÓIšf˜¯©¯°C¸B¿L¹LÑ(H—1™fˆÐIÜ"ØØØ*´sÑPWÓ;XÒPWÈ1¿J¼JÑPWÑ;XÓ7YÑZÐ[ØDJÂOÓTÂO¸qÐ:�q—|‘|“~Ð: v¨q¯v©v¸©zÔ:ÁOÑTØ—l‘lÜ˜“LÜ˜&“k¤C¨£LÑ0ñ
ˆŒ÷ e×dð  �5ˆ=ÐùóY Dùó 4ò, eÚZùò <ùÚIùò <YùÚT÷ e×d×dð  �5ˆ=Ðüsº   …-J²IÁIÁ"JÁ5I ÂAJÃ"I&Ã#JÃ&JÄI)ÄAJÅI,Å1I,Å7JÅ=&I1Æ'I1Æ-JÇ I6ÇJÇ$-I;È5JÉJÉJ ÉJÉ)JÉ,JÊ JÊJÊJÊ	JÊ
Jc              ƒ  ó&  #   • [        5       R                  n[        R                  " 5       n[	        X5      I Sh  v•N u  pEU Vs1 s H!  ofR
                  (       d  M  UR                  iM#     nn[        XU5      I Sh  v•N u  p‰[        UUUR                  U	R                  =(       d    UR                  [        R                  " 5       U-
  UR                  U	R                  -   [        UR                  U	R                  -   5      S9$  NÍs  snf  N�7f)z>Both passes over the candidates, with everything Jev returned.N)rQ   rR   rT   rU   rW   rX   rZ   )r   rƒ   rØ   rÙ   r  rA   r?   r$  rO   rT   rU   rX   rx   rZ   )
r'   r(   r‰   rÛ   rQ   Ú
page_tallyru   r  rR   Úchunk_tallys
             r)   rM   rM   Œ  s×   é € ä	‹×	 Ñ	 €BÜ×ÒÓ!€GÜ)¨(Ó:×:Ñ€EÙ!Ó0šE�q§Z¥Z‹FˆA�FŒF™E€DÐ0Ü ,¨X¸dÓ C×CÑ€FÜØØØ—,‘,Ø×Ñ×3 :×#3Ñ#3Ü×!Ò!Ó# gÑ-Ø×,Ñ,¨{×/GÑ/GÑGÜ�j×)Ñ)¨K×,@Ñ,@Ñ@ÓAñð ñ ;ùÚ0ÙCùs4   ‚8DºD»
DÁD
ÁD
Á-DÁ>DÁ?B
DÄ
Dc              ƒ  ó  #   • [        X5      I Sh  v•N nUR                  5       n[        R                  " S[	        UR
                  5      [	        UR                  5       5      [	        UR                  5      [	        U5      UR                  5       UR                  UR                  UR                  UR                  =(       d    S5
        UR
                   Vs/ s H  oDR                  (       d  M  UPM     nnUR                   Vs/ s H  ofR                  (       d  M  UPM     nnU(       d  U(       a{  [        R                  " S[	        U5      [	        U5      U Vs/ s H  oDR                  S-   UR                  4PM     snU Vs/ s H  ofR                   UR                  4PM     sn5        UR                  R#                  S5      (       a$  [        R                  " SUR                  S   5        U$  GNäs  snf s  snf s  snf s  snf 7f)zDIndices into `cands` in the order the answer model should read them.Nz�jev ranker: {} pages judged, {} kept; {} of {} candidates graded, {} cleared the cut of {}; {:.1f}s, {} input tokens, failures {}ÚnonezNjev ranker: {} page calls and {} chunk calls failed twice; pages {}; chunks {}rl   Ú429zdjev ranker: {} calls were throttled (429) past the SDK's retries; TypeSafe's limits may have changed)rM   rh   r   Údebugr  rQ   rv   rR   rr   rT   rW   rX   rZ   rE   Úwarningr?   rK   ré   )r'   r(   Úrankingrh   ru   Úfailed_pagesr  Úfailed_chunkss           r)   Úrankr0  ž  s}  é € ä˜(Ó*×*€GØ�M‰M‹O€EÜ
‡L‚Lð	0äˆG�M‰MÓÜˆG×ÑÓ Ó!ÜˆG�N‰NÓÜˆE‹
Ø�‰ÓØ×ÑØ�‰Ø×ÑØ×Ñ×"˜Fôð  'Ÿ}š}Ó8š}˜!·µ—A™}€LÐ8Ø '§¢Ó:¢˜1·'µ'—Q¡€MÐ:Þ–}Ü�ŠØ\Ü�ÓÜ�ÓÙ,8Ó9ªL q�f‰f�q‰j˜!Ÿ'™'Ó"©LÑ9Ù,9Ó:ªM q�j‰j˜!Ÿ'™'Ó"©MÑ:ô	
ð ×Ñ×Ñ˜E×"Ñ"Ü�ŠØrØ×Ñ˜UÑ#ô	
ð €Lò= +ùò 9ùÚ:ùò :ùÚ:ùsS   ‚H‘G5’CHÃG8Ã0G8Ã6HÄG=ÄG=Ä$9HÅ$HÆHÆ!HÆ(AHÇ8Hc                ó@   • [         R                  " [        X5      5      $ r$   )r¿   r
  r0  )r'   r(   s     r)   Ú	rank_syncr2  Á  s   € Ü�;Š;”t˜HÓ,Ó-Ð-r7   )r/   r   )r(   r.   r/   zDict[int, str])
r“   zList[T]rµ   zCallable[[T], Awaitable[Any]]rg   zCallable[[Any], bool]rÅ   r>   r/   z	List[Any])r/   r-   )rÚ   r�   rÛ   rS   rÜ   r   r/   zDict[str, Any])r'   r-   r(   r.   r/   ztuple[List[PageScore], _Tally])r'   r-   r(   r.   r  zset[int]r/   ztuple[List[ChunkScore], _Tally])r'   r-   r(   r.   r/   rO   r,   )Fr5   Ú
__future__r   r¿   rØ   Úcollectionsr   Ú	functoolsr   Útypingr   r   r   r	   r
   r   r   r   r   r…   Úlogurur   Úpydanticr   r   Útypesafe_sdkr   r   r   r   r   r   r   r   Úquber.agents.langsmith_tracerr   Úquber.playgroundr   Úquber.playground.tracingr   r   Úquber.settingsr   Úquber.playground.retrievalr   r!   r  r"  rÏ   rÐ   rÑ   rÒ   rë   r  rî   r<   rH   rO   r‹   rš   r›   r�   rÉ   rÓ   rÝ   r  r$  rM   r0  r2  r%   r7   r)   Ú<module>r?     s’  ðñõB #ã Û Ý Ý ÷
÷ 
õ 
ó Ý ß %÷	÷ 	ó 	õ >Ý ß 9Ý 'æÝ9ô]�(ô ]ðUð ð <€à]€ð&ð ð
7ð ð j€ñ ˜Ñ'€ÙØ¨?Ð<LÈnÐ^jÐ*kñ	€ð €ô �	ô  ô �ô  ô:ˆiô :ñ< �1Ñóó ðô$Añ> ˆCƒL€÷ñ ð*ØðØ7ðØAVðØehðàôô(ôô/ðd3Øð3Ø0ð3Ø8@ð3à$ô3ôlô$ õF.r7   