+
    Ôñ·j§'  ã                   ó¬   € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt	^ RI
Ht ^tRtRtRRRuttt^	t^<t^xtRtRtRtR	 t ! R
 R4      tRR ltR# )u®  Server side of the æµ�è§ˆå™¨ vs æœ�åŠ¡ç«¯ page (www/server-compute/): runs the native build of the
demos' own Rust code (crates/native/compute â†’ target/release/compute) and hands the results to
the page. Enabled by `serve.py --mcp mcp.config.json --compute`; it uses the MCP bridge's
access rules (local token, or a remote session), since it spends this machine's CPU.

  GET  /api/compute/info      {"available", "cores", "limits", "hint"}
  POST /api/compute/bench     {"task": sha256|deflate|sudoku, "size": n} â†’ the program's JSON
                              plus "server_ms" (the whole run, as the page's round trip sees it)
  POST /api/compute/gomoku    {"board": 225 Ã— '0'/'1'/'2', "depth": 1..MAX_GOMOKU_DEPTH, "threads": n}
                              â†’ the move the browser AI would pick at that depth, searched on n threads
  GET  /api/compute/render?w=&h=&spp=&scene=&threads=
                              server-sent events: the program's lines, one band of rows each

At most MAX_JOBS programs run at once (then 429); each is killed after its timeout, and a
render also when the page goes away. Arguments are checked here before anything starts,
and again by the program.
N)ÚBridgeErroré   éè  i   iÐ  i   u;   å…ˆç¼–è¯‘æœ�åŠ¡ç«¯ç¨‹åº�ï¼šcargo build --release -p computec           	     ó¨   € \        V \        4      '       g'   \        V \        4      '       d   Yu;8:  d   V8:  g   M \        RV RV RV R24      hV # )z8An int in [lo, hi] (not a bool, not a string), else 400.é�  u    å¿…é¡»æ˜¯ u    åˆ° u    ä¹‹é—´çš„æ•´æ•°)Ú
isinstanceÚboolÚintr   )ÚvalueÚloÚhiÚwhats   &&&&Ú./work/data/stt/webtt/scripts/compute_bridge.pyÚwhole_numberr   )   sL   € ä�%œ×Ò¤j°¼×&<Ò&<ÀBÖDUÐSUÖDUÜ˜# $  {°2°$°e¸B¸4Ð?OÐPÓQÐQØ€Ló    c                   ó|   a € ] tR t^0t o RR ltR tR tR tR tR t	R t
R	 t]R
 4       tR tR tR tR tRtV tR# )ÚComputeBridgeNc                ó  € \         P                  ! V4      V n        W n        T;'       g    \        V n        T;'       g    \        V n        \        P                  ! \        4      V n        \        P                  ! 4       V n        ^ V n        R# )é    N)ÚpathlibÚPathÚbinaryÚ	authorizeÚBENCH_TIMEOUTÚbench_timeoutÚRENDER_TIMEOUTÚrender_timeoutÚ	threadingÚBoundedSemaphoreÚMAX_JOBSÚslotsÚLockÚlockÚrunning)Úselfr   r   Útimeouts   &&&&r   Ú__init__ÚComputeBridge.__init__1   s^   € Ü—l’l 6Ó*ˆŒØ"ŒØ$×5Ð5¬ˆÔØ%×7Ð7¬ˆÔÜ×/Ò/´Ó9ˆŒ
Ü—N’NÓ$ˆŒ	ØˆŽr   c                ó¤   € V P                   P                  4       ;'       d0    \        P                  ! V P                   \        P                  4      # ©N)r   Úis_fileÚosÚaccessÚX_OK©r$   s   &r   Ú	availableÚComputeBridge.available:   s0   € Ø�{‰{×"Ñ"Ó$×HÐH¬¯ª°4·;±;ÄÇÁÓ)HÐHr   c                ó.  € R V P                  4       R\        P                  ! 4       RV P                  RR\        R\
        R\        R\        R\        R	\        R
\        RV P                  RV P                  /	RV P                  4       '       d   R/# \        /# )r/   Úcoresr#   ÚlimitsÚmax_jobsÚmax_mibÚ
max_roundsÚmax_wÚmax_gomoku_depthÚmax_hÚmax_sppÚbench_timeout_sÚrender_timeout_sÚhintÚ )r/   r+   Ú	cpu_countr#   r   ÚMAX_MIBÚ
MAX_ROUNDSÚMAX_WÚMAX_GOMOKU_DEPTHÚMAX_HÚMAX_SPPr   r   Ú
BUILD_HINTr.   s   &r   ÚinfoÚComputeBridge.info=   s•   € Ø˜TŸ^™^Ó-¨w¼¿º»È	ÐSW×S_ÑS_Ø˜:¤x°¼GÀ\ÔS]Ð_fÔhmØ-Ô/?Ø"¤E¨9´gÐ?PÐRV×RdÑRdØ-¨t×/BÑ/BðDð ˜dŸn™n×.Ò.˜ð@ð 	@ô
 5?ð@ð 	@r   c                óŽ   € V P                  4       '       d   V P                   MV P                   R \         R2pRV R\         R2# )u    ä¸�å­˜åœ¨ï¼ˆu   ï¼‰zCompute API: z
; at most z jobs at once)r/   r   rF   r   )r$   Ústates   & r   Ústartup_lineÚComputeBridge.startup_lineE   sD   € Ø$(§N¡N×$4Ò$4�4—;‘;‘-¸T¿[¹[¸MÈÔWaÐVbÐbeÐ:fˆØ˜u˜g Z´¨z¸ÐGÐGr   c           	     ó¸  € \         P                  P                  VP                  4      pVP                  P	                  R4      '       g   R#  V P                  V4       VP                  \        R4      R pVR8X  d%   VR8X  d   \        V^ÈV P                  4       4       R# VR8X  d   VR8X  d   V P                  V4       R# VR8X  d   VR8X  d   V P                  V4       R# VR8X  dC   VR	8X  d<   V P                  V\         P                  P                  VP                  4      4       R# \        R
R4      h  \         dD   p\        YP                  R\!        T4      /TP"                  CTP$                  4        Rp?R# Rp?i\&         dJ   p\(        P*                  ! 4         \        TRRRT 2/4        Rp?R#   \,         d	      Rp?R# i ; iRp?ii ; i)zDServe an /api/compute request. Returns False if the path isn't ours.z/api/compute/FNÚGETrG   ÚPOSTÚbenchÚgomokuÚrenderi”  u   æœªçŸ¥çš„è·¯å¾„Úerroréô  u   è®¡ç®—æœ�åŠ¡å†…éƒ¨é”™è¯¯ï¼šT)ÚurllibÚparseÚurlsplitÚpathÚ
startswithr   ÚlenÚ
reply_jsonrG   rP   rQ   rR   Úparse_qsÚqueryr   ÚstatusÚstrÚextraÚheadersÚ	ExceptionÚ	tracebackÚ	print_excÚOSError)r$   ÚhandlerÚmethodÚurlÚrouteÚes   &&&   r   ÚhandleÚComputeBridge.handleK   s›  € ä�l‰l×#Ñ# G§L¡LÓ1ˆØ�x‰x×"Ñ" ?×3Ò3Ùð	Ø�N‰N˜7Ô#Ø—H‘HœS Ó1Ð2Ð3ˆEØ˜Œ 5¨F¤?Ü˜7 C¨¯©«Ô5ñ" ð! ˜6Ô! e¨wÔ&6Ø—
‘
˜7Ô#ñ ð ˜6Ô! e¨xÔ&7Ø—‘˜GÔ$ñ ð ˜5” U¨hÔ%6Ø—‘˜G¤V§\¡\×%:Ñ%:¸3¿9¹9Ó%EÔFñ ô " #Ð'8Ó9Ð9øÜô 	SÜ�w§¡¨7´C¸³FÐ*F¸a¿g¹gÐ*FÈÏ	É	×RÐRñ ûô ô 	Ü×ÒÔ!ðÜ˜7 C¨'Ð5PÐQRÐPSÐ3TÐ)U×VÐVñ øô ô ÜÙðþð		úsb   ÁAD9 Â"D9 ÃD9 Ã$AD9 Ä-D9 Ä9GÅ8FÆGÆGÆGÆ&F>Æ>GÇ	GÇGÇGÇGc                óÆ   € V P                  4       '       g   \        R\        4      hV P                  P	                  RR7      '       g   \        RR\
         R2/ RR/4      hV # )	z9A slot for one program, or 429 when MAX_JOBS already run.i÷  F)Úblockingi­  u   æœ�åŠ¡ç«¯å·²æœ‰ u%    ä¸ªè®¡ç®—åœ¨è¿�è¡Œï¼Œè¯·ç¨�å�Žå†�è¯•zRetry-AfterÚ5)r/   r   rF   r    Úacquirer   r.   s   &r   ÚjobÚComputeBridge.jobg   sc   € à�~‰~×ÒÜ˜c¤:Ó.Ð.Ø�z‰z×!Ñ!¨5Ð!×1Ò1Ü˜cÐ%5´h°ZÐ?dÐ#eÐgiÐlyÐ{~Ðkó  Að  AØˆr   c                óš   € V P                   ;_uu_ 4        V ;P                  ^,          un        RRR4       R#   + '       g   i     R# ; i©é   N)r"   r#   r.   s   &r   Ú	__enter__ÚComputeBridge.__enter__o   s%   € Ø�Y�Y‹YØ�LŠL˜AÕ�L÷ �Y�YŠYús	   •9¹A
	c                óÌ   € V P                   ;_uu_ 4        V ;P                  ^,          un        RRR4       V P                  P                  4        R#   + '       g   i     L,; irt   )r"   r#   r    Úrelease)r$   Úexcs   &*r   Ú__exit__ÚComputeBridge.__exit__s   s6   € Ø�Y�Y‹YØ�LŠL˜AÕ�L÷ à�
‰
×ÑÖ÷ �Yús   •AÁA#	c                óÖ  €  \        V P                  P                  R 4      ;'       g    ^ 4      p^ Tu;8  d   \
        8:  g   M \	        RR4      h \        P                  ! T P                  P                  T4      4      p\        T\        4      '       g   \	        RR4      hT#   \         d    \	        RR4      hi ; i  \        P                  \        3 d    \	        RR4      hi ; i)úContent-Lengthr   u   Content-Length ä¸�æ˜¯æ•°å­—u   è¯·æ±‚ä½“ä¸ºç©ºæˆ–è¿‡å¤§u   ä¸�æ˜¯å�ˆæ³•çš„ JSONu   éœ€è¦�ä¸€ä¸ª JSON å¯¹è±¡)r	   ra   ÚgetÚ
ValueErrorr   ÚMAX_BODYÚjsonÚloadsÚrfileÚreadÚJSONDecodeErrorÚUnicodeDecodeErrorr   Údict)rf   ÚlengthÚbodys   &  r   Ú	json_bodyÚComputeBridge.json_bodyz   sÖ   € ð	BÜ˜Ÿ™×,Ñ,Ð-=Ó>×CÐCÀ!ÓDˆFð �6Ö%œXÖ%Ü˜cÐ#=Ó>Ð>ð	;Ü—:’:˜gŸm™m×0Ñ0°Ó8Ó9ˆDô ˜$¤×%Ò%Ü˜cÐ#=Ó>Ð>Øˆøô ô 	BÜ˜cÐ#@ÓAÐAð	Bûô ×$Ñ$Ô&8Ð9ô 	;Ü˜cÐ#9Ó:Ð:ð	;ús   ‚&B% ©B% Á/C  Â%B=Ã (C(c           
     ód  € V P                  4       ;_uu_ 4        \        P                  ! 4       p \        P                  ! \        V P                  4      .VORRV P                  R7      p\        P                  ! 4       T,
          R,          pRRR4       XP                  ^ 8w  dd   TP                  P                  4       P                  4       ;'       g    R.^ ,          p\        TP                  ^8X  d   R	MR
RTR,           24      h\        P                  ! TP                   P                  4       P                  4       R,          4      p\#        T^È/ TCR\%        X^4      /C4       R#   \        P                   d    \        RRT P                   R24      hi ; i  + '       g   i     EL; i)zRun the program to completion and answer with its JSON line plus "server_ms". Exit
code 2 means it refused the arguments (400).T)Úcapture_outputÚtextr%   iø  õ   è¶…è¿‡ õ    ç§’æœªå®Œæˆ�ï¼Œå·²ç»ˆæ­¢r   Nr>   r   rT   u   è®¡ç®—ç¨‹åº�æ‹’ç»�æˆ–å‡ºé”™ï¼š:Ni,  NÚ	server_mséÿÿÿÿ)rq   ÚtimeÚ	monotonicÚ
subprocessÚrunr_   r   r   ÚTimeoutExpiredr   Ú
returncodeÚstderrÚstripÚ
splitlinesr‚   rƒ   Ústdoutr[   Úround)r$   rf   ÚargsÚt0Úprocr’   ÚfirstÚresults   &&&     r   Úrun_onceÚComputeBridge.run_onceŠ   sX  € ð �X‰X�Z�ZÜ—’Ó!ˆBð`Ü!—~’~¤s¨4¯;©;Ó'7Ð&?¸$Ð&?ÐPTÐ[_Ðim×i{Ñi{Ô|�ô ŸšÓ)¨BÕ.°$Õ6ˆI÷ ð �?‰?˜aÔØ—[‘[×&Ñ&Ó(×3Ñ3Ó5×=Ð=¸"¸¸qÕAˆEÜ T§_¡_¸Ô%9™c¸sÐFdÐejÐkoÕepÐdqÐDrÓsÐsÜ—’˜DŸK™K×-Ñ-Ó/×:Ñ:Ó<¸RÕ@ÓAˆÜ�7˜CÐ!M FÐ!M¨K¼¸yÈ!Ó9LÑ!MÖNøô ×,Ñ,ô `Ü! #¨°×1CÑ1CÐ0DÐD]Ð'^Ó_Ð_ð`ú÷	 �ZˆZús"   ™F°:E+Á*#FÅ+0FÆFÆF/	c                óL  € V P                  V4      pVP                  R 4      \        9  d$   \        RRRP	                  \        4       R24      hVR ,          p\        VP                  R4      ^VR8X  d   \        M\        R4      pV P                  VRV\        V4      .4       R# )	Útaskr   u   task å¿…é¡»æ˜¯ u   ã€�u    ä¹‹ä¸€ÚsizeÚsudokurP   N)
r‹   r   ÚTASKSr   Újoinr   rA   r@   r¤   r_   )r$   rf   rŠ   r§   r¨   s   &&   r   rP   ÚComputeBridge.benchš   s‡   € Ø�~‰~˜gÓ&ˆØ�8‰8�FÓ¤5Ô(Ü˜c _°U·Z±ZÄÓ5FÐ4GÀwÐ#OÓPÐPØ�F�|ˆÜ˜DŸH™H VÓ,¨a¸tÀxÔ?OµÔU\Ð^dÓeˆØ�‰�g ¨¬s°4«yÐ9Ö:r   c           	     óJ  € V P                  V4      pVP                  R 4      p\        V\        4      '       d#   \	        V4      ^á8X  d   \        V4      0 R
m8:  g   \        RR4      hVP                  R4      VP                  R4      ,
          R9  d   \        RR4      h\        VP                  R4      ^\        R4      p\        VP                  R^4      ^\        P                  ! 4       ;'       g    ^R4      pV P                  VRV\        V4      \        V4      .4       R	# )ÚboardÚ1Ú2r   uC   board å¿…é¡»æ˜¯ 225 ä¸ª 0ã€�1ã€�2 ç»„æˆ�çš„å­—ç¬¦ä¸²ï¼ˆè¡Œä¼˜å…ˆï¼‰u/   é»‘å­�æ•°åº”ç­‰äºŽç™½å­�æ•°æˆ–å¤š 1ï¼ˆé»‘å…ˆï¼‰ÚdepthÚthreadsrQ   N>   Ú0r¯   r°   )r   ru   )r‹   r   r   r_   rZ   Úsetr   Úcountr   rC   r+   r?   r¤   )r$   rf   rŠ   r®   r±   r²   s   &&    r   rQ   ÚComputeBridge.gomoku¢   sÞ   € Ø�~‰~˜gÓ&ˆØ—‘˜Ó!ˆÜ˜5¤#×&Ò&¬3¨u«:¸Ô+<ÄÀUÃÊÔA^Ü˜cÐ#hÓiÐiØ�;‰;�sÓ˜eŸk™k¨#Ó.Õ.°fÔ<Ü˜cÐ#TÓUÐUÜ˜TŸX™X gÓ.°Ô3CÀWÓMˆÜ˜tŸx™x¨	°1Ó5°q¼"¿,º,».×:MÐ:MÈAÈyÓYˆØ�‰�g ¨%´°U³¼SÀ»\ÐJÖKr   c                ó  a€ V3R  lpV! R^\         4      V! R^\        4      V! R^\        4      V! R^ ^4      T! R^\        P                  ! 4       ;'       g    ^4      .pV P                  4       ;_uu_ 4        \        P                  ! \        V P                  4      R.\        \        V4      O\        P                  \        P                  RR7      p\        P                  ! V P                  VP                   4      pVP#                  4         VP%                  ^È4       VP'                  R	R
4       VP'                  RR4       VP)                  4        VP*                   FX  pVP,                  P/                  RVP1                  4        R2P3                  4       4       VP,                  P5                  4        KZ  	  VP7                  4       ^ 8w  dp   VP9                  4       '       g   RV P                   R2MRpVP,                  P/                  R\:        P<                  ! RRRV/RR7       R2P3                  4       4       TPA                  4        TP!                  4        TP7                  4        TP*                  PC                  4         RRR4       R#   \>         d     Lbi ; i  TPA                  4        TP!                  4        TP7                  4        TP*                  PC                  4        i ; i  + '       g   i     R# ; i)c                 óž   <€  \        \        SP                  V R .4      ^ ,          4      WV 4      #   \         d    \	        RT  R24      hi ; i)r>   r   u    å¿…é¡»æ˜¯æ•´æ•°)r   r	   r   r€   r   )Únamer   r   r]   s   &&&€r   ÚargÚ!ComputeBridge.render.<locals>.arg°   sU   ø€ ðBÜ#¤C¨¯	©	°$¸¸Ó(=¸aÕ(@Ó$AÀ2È4ÓPÐPøÜô BÜ! #¨$¨Ð/?Ð'@ÓAÐAðBús	   ƒ-1 ±AÚwÚhÚsppÚscener²   rR   T)r�   rš   r�   úContent-Typez text/event-stream; charset=utf-8zCache-Controlzno-cachezdata: z

r�   r‘   u   è®¡ç®—ç¨‹åº�å‡ºé”™ÚtyperS   ÚmessageF©Úensure_asciiN)"rB   rD   rE   r+   r?   rq   r–   ÚPopenr_   r   ÚmapÚPIPEÚDEVNULLr   ÚTimerr   ÚkillÚstartÚsend_responseÚsend_headerÚend_headersr�   ÚwfileÚwriter›   ÚencodeÚflushÚwaitÚis_aliver‚   Údumpsre   ÚcancelÚclose)	r$   rf   r]   rº   rŸ   r¡   ÚtimerÚlineÚwhys	   &&f      r   rR   ÚComputeBridge.render¯   sP  ø€ õ	Bñ
 �C˜œEÓ"¡C¨¨Q´Ó$6¹¸EÀ1ÄgÓ8NÑPSÐT[Ð]^Ð`aÓPbÙ�I˜q¤"§,¢,£.×"5Ð"5°AÓ6ð8ˆà�X‰X�Z�ZÜ×#Ò#¤S¨¯©Ó%5°xÐ$QÄ#ÄcÈ4Ã.Ð$QÔZd×ZiÑZiÜ+5×+=Ñ+=ÀDôJˆDä—O’O D×$7Ñ$7¸¿¹ÓCˆEØ�K‰KŒMð$Ø×%Ñ% cÔ*Ø×#Ñ# NÐ4VÔWØ×#Ñ# O°ZÔ@Ø×#Ñ#Ô%Ø ŸKœK�DØ—M‘M×'Ñ'¨&°·±³°¸dÐ(C×(JÑ(JÓ(LÔMØ—M‘M×'Ñ'Ö)ñ (ð —9‘9“; !Ô#ØZ_×ZhÑZh×ZjÒZj˜G D×$7Ñ$7Ð#8Ð8QÑRð  qE�CØ—M‘M×'Ñ'¨&´·²¸VÀWÈiÐY\Ð<]ÐlqÔ1rÐ0sÐswÐ(x×(Ñ(ó  )Bô  Cð —‘”Ø—	‘	”Ø—	‘	”Ø—‘×!Ñ!Õ#÷- ‰Zøô  ô Ùðûð —‘”Ø—	‘	”Ø—	‘	”Ø—‘×!Ñ!Õ#ú÷- �ZˆZúsG   Á8BK6ÄCJÇ(AJÉA
K6ÊJ$Ê!J'Ê#J$Ê$J'Ê'AK3Ë3K6Ë6L	)r   r   r   r"   r   r#   r    r)   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r&   r/   rG   rK   rk   rq   rv   r{   Ústaticmethodr‹   r¤   rP   rQ   rR   Ú__static_attributes__Ú__classdictcell__)Ú__classdict__s   @r   r   r   0   s_   ø‡ € ôòIò@òHòò8òòð ñó ðòOò ;ò	L÷$ð $r   r   c                 óž  € \         P                  ! VR R7      P                  4       pV P                  V4       V P	                  RR4       T;'       g    / P                  4        F  w  rVV P	                  WV4       K  	  V P	                  R\        \        V4      4      4       V P                  4        V P                  P                  V4       R# )FrÃ   rÀ   zapplication/json; charset=utf-8r~   N)r‚   rÕ   rÑ   rÌ   rÍ   Úitemsr_   rZ   rÎ   rÏ   rÐ   )rf   r^   Úobjra   rŠ   r¹   r
   s   &&&&   r   r[   r[   Ð   sš   € Ü�:Š:�c¨Ô.×5Ñ5Ó7€DØ×Ñ˜&Ô!Ø×Ñ˜Ð(IÔJØŸ˜ 2×,Ñ,Ö.‰ˆØ×Ñ˜DÖ(ñ /à×ÑÐ(¬#¬c°$«i«.Ô9Ø×ÑÔØ‡M�M×Ñ˜Ör   )Úsha256Údeflater©   r)   )Ú__doc__r‚   r+   r   r–   r   r”   rc   Úurllib.parserU   Ú
mcp_bridger   r   r@   rA   rB   rD   rE   rC   r   r   r�   rª   rF   r   r   r[   © r   r   Ú<module>rí      s|   ðñó" Û 	Û Û Û Û Û Û å "à€Ø
€Ø€
Ø˜c 3Ð €€uˆgØÐ Ø€Ø€Ø€Ø'€ØJ€
ò÷]$ñ ]$ö@r   