+
    fiB                        R t ^ RIH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
Ht ^ RIHt ^ RIHtHt ^ RIt^ RIHt ]P(                  ! ]4      tRtRtR	tR
RRRRR/tRRRRRRRR/tRRRRRR/tRtRRR R!R"R#R$R%/t ! R& R']4      tR# )(u  
Google Flow API v2 Provider — uses the newer flowMedia:batchGenerateImages endpoint.

This provider accesses newer models like GEM_PIX_2 and IMAGEN_4 that are NOT available
on the legacy v1:runImageFx endpoint.

Requirements (from browser DevTools → Network tab):
  - GOOGLE_FLOW_PROJECT_ID: Your Google Labs project ID
  - GOOGLE_FLOW_SESSION_TOKEN: __Secure-next-auth.session-token cookie
  - GOOGLE_FLOW_CSRF_TOKEN: __Host-next-auth.csrf-token cookie
  - GOOGLE_FLOW_RECAPTCHA_TOKEN: reCAPTCHA Enterprise token (from network requests)

HOW TO GET YOUR TOKENS:
1. Open https://labs.google/fx/tools/image-fx in Chrome
2. Open DevTools (F12) → Network tab
3. Generate an image in the UI
4. Find the POST to aisandbox-pa.googleapis.com/.../flowMedia:batchGenerateImages
5. From the request payload, extract:
   - client_context.project_id → GOOGLE_FLOW_PROJECT_ID
   - client_context.recaptcha_context.token → GOOGLE_FLOW_RECAPTCHA_TOKEN
6. Cookies are the same as the legacy provider.
)annotationsN)datetimetimezone)Path)AnyOptional)ImageProviderz'https://labs.google/fx/api/auth/sessionzZhttps://aisandbox-pa.googleapis.com/v1/projects/{project_id}/flowMedia:batchGenerateImagesz1https://aisandbox-pa.googleapis.com/v1:runImageFxportraitIMAGE_ASPECT_RATIO_PORTRAIT	landscapeIMAGE_ASPECT_RATIO_LANDSCAPEsquareIMAGE_ASPECT_RATIO_SQUARE	gem_pix_2	GEM_PIX_2imagen_4IMAGEN_4nano_banana_proNANO_BANANA_PROnano_bananaNANO_BANANA
imagen_3_5
IMAGEN_3_5imagen_3_5_fastIMAGEN_3_5_FASTimagen_3IMAGEN_3Originzhttps://labs.googleRefererz%https://labs.google/fx/tools/image-fxzContent-Typezapplication/jsonz
User-AgentzeMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36c                      ] tR t^StRtRtR tR R ltR R ltR R	 lt	R
 R lt
R R ltR!R R lltR!R R lltR"R R lltR!R R lltR"R R lltR R ltR"R R lltR tR tR tR tR# )#GoogleFlowV2ImageProviderzVGenerates images via Google Flow API (newer endpoint with GEM_PIX_2/IMAGEN_4 support).google_flow_v2c                	   \         P                  ! R R4      V n        \         P                  ! RR4      V n        \         P                  ! RR4      V n        \         P                  ! RR4      V n        \        P                  \         P                  ! RR4      P                  4       R4      V n	        \         P                  ! RR	4      P                  4       p/ \        C\        CpVP                  WP                  4       4      V n        \        V P                  4      V n        V P                  '       g   \!        R
4      hV P                  '       g   \!        R4      hV P                  '       gl   V P                  \        P#                  4       9   d(   \$        P'                  RV P                  4       RV n        \$        P)                  RV P                  4       MN\$        P)                  RV P                  V P                  R,          R,           V P
                  '       d   RMR4       RV n        RV n        RV n        \0        P2                  ! ^ZRR7      V n        R# )GOOGLE_FLOW_SESSION_TOKEN GOOGLE_FLOW_CSRF_TOKENGOOGLE_FLOW_PROJECT_IDGOOGLE_FLOW_RECAPTCHA_TOKENGOOGLE_FLOW_ASPECT_RATIOr	   r
   GOOGLE_FLOW_MODELr   u`   GOOGLE_FLOW_SESSION_TOKEN is required. Extract from Chrome DevTools → Application → Cookies.u]   GOOGLE_FLOW_CSRF_TOKEN is required. Extract from Chrome DevTools → Application → Cookies.zModel %s requires Flow API (project_id needed). Falling back to IMAGEN_3_5 on legacy endpoint. Run Auto Setup in settings to enable Flow API.r   u2   Using LEGACY endpoint (v1:runImageFx) — model=%suS   Using FLOW API (flowMedia:batchGenerateImages) — model=%s project=%s recaptcha=%s:N   Nz...yeszno (will try without)NT)timeoutfollow_redirects)osgetenvsession_token
csrf_token
project_idrecaptcha_tokenASPECT_RATIOSgetloweraspect_ratioFLOW_MODELSLEGACY_MODELSuppermodelbool_use_flow_apiEnvironmentErrorvaluesloggerwarninginfo_access_token_token_expiry_last_media_idhttpxClientclient)self	model_key
all_modelss   &  $providers/google_flow_v2_provider.py__init__"GoogleFlowV2ImageProvider.__init__X   s   YY'BBG))$<bA))$<bA!yy)FK)--II0*=CCE)

 II1;?EEG	55}5
^^I/@A
 "$//2!!!"L  "L 
 !!!zz[//11E JJ	 *
KKLdjjYKKe

$u,---3J	 *..2*.ll2E    c                   V ^8  d   QhRR/#    returnstr )formats   "rL   __annotate__&GoogleFlowV2ImageProvider.__annotate__   s     
 
 
rO   c                	:    R V P                    RV P                   2# )!__Secure-next-auth.session-token=z; __Host-next-auth.csrf-token=)r0   r1   rI   s   &rL   _cookie_string(GoogleFlowV2ImageProvider._cookie_string   s*    /0B0B/C D++/??*;=	
rO   c                    V ^8  d   QhRRRR/# )rR   responsezhttpx.ResponserS   NonerU   )rV   s   "rL   rW   rX      s     	 	~ 	$ 	rO   c                	F   VP                   P                  R 4       F  pRV9   g   K  VP                  R4      ^,          pVP                  R4      ^ ,          pV'       d=   W0P                  8w  d-   W0n        \        P                  R4       V P                  V4        R# 	  R# )z
set-cookierZ   ;zSession cookie rotatedN)headersget_listsplitr0   r@   debug_persist_token)rI   r_   cookie_headertokens   &&  rL   _update_session_cookie0GoogleFlowV2ImageProvider._update_session_cookie   s    %--66|DM2mC%++,OPQRSC(+U&8&88).&LL!9:''. ErO   c                    V ^8  d   QhRRRR/# )rR   ri   rT   rS   r`   rU   )rV   s   "rL   rW   rX      s     E EC ED ErO   c                	j   \        \        4      P                  4       P                  P                  R ,          pVP	                  4       '       g   R#  VP                  RR7      pRV9   d   VP                  4       p. pV FA  pVP                  R4      '       d   VP                  RV 24       K0  VP                  V4       KC  	  VP                  RP                  V4      R,           RR7       \        P                  R4       R# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z.envNzutf-8)encodingzGOOGLE_FLOW_SESSION_TOKEN=
zUpdated session token in .envz#Could not persist rotated token: %s)r   __file__resolveparentexists	read_text
splitlines
startswithappend
write_textjoinr@   rB   	ExceptionrA   )rI   ri   env_pathcontentlines	new_lineslinees   &&      rL   rg   (GoogleFlowV2ImageProvider._persist_token   s   >))+2299FB  	E(('(:G+w6**,	!D'CDD!((+EeW)MN!((.	 "
 ##DIIi$84$?'#R;< 7  	ENN@!DD	Es   B0D D2D--D2c                   V ^8  d   QhRR/# rQ   rU   )rV   s   "rL   rW   rX      s     &" &"s &"rO   c                	   V P                   '       dR   V P                  '       d@   \        P                  ! \        P
                  4      V P                  8  d   V P                   # \        P                  R 4       V P                  P                  \        / \        CRV P                  4       /CR7      pV P                  V4       VP                  4        VP                  4       pVP                  R4      ;'       g    VP                  R4      V n         VP                  R4      pV P                   '       g'   \!        R\#        VP%                  4       4       R24      hV'       d-    \        P&                  ! VP)                  RR	4      4      V n        \        P                  RV P                  '       d   V P                  P-                  4       MR4       V P                   #   \*         d    R
T n         Lbi ; i)z/Refreshing access token via session endpoint...Cookierc   access_tokenaccessTokenexpiresz+No access_token in session response. Keys: u4   . Cookies may be expired — re-extract from Chrome.Zz+00:00Nz"Access token obtained (expires %s)unknown)rC   rD   r   nowr   utcr@   rB   rH   r5   SESSION_URLDEFAULT_HEADERSr\   rj   raise_for_statusjsonRuntimeErrorlistkeysfromisoformatreplace
ValueError	isoformat)rI   respdataexpires_strs   &   rL   _refresh_access_token/GoogleFlowV2ImageProvider._refresh_access_token   s   """X\\*T-?-??%%%EF{{HH$2E2E2GH  
 	##D)yy{!XXn5PP-9Phhy)!!!=d499;>O=P QE E 
 *%-%;%;''X6&" 	0.2.@.@.@D((*i	
 !!!  *%)"*s   $+G G21G2c                   V ^8  d   QhRR/# )rR   rS   zdict[str, str]rU   )rV   s   "rL   rW   rX      s     
 
~ 
rO   c                	`    V P                  4       p/ \        CR V P                  4       RRV 2/C# )r   AuthorizationzBearer )r   r   r\   )rI   ri   s   & rL   _auth_headers'GoogleFlowV2ImageProvider._auth_headers   sA    **,

d))+wug.
 	
rO   Nc               $    V ^8  d   QhRRRRRR/# )rR   promptrT   seed
int | NonerS   dictrU   )rV   s   "rL   rW   rX      s!     
 
s 
* 
 
rO   c                P   Vf   \         P                  ! RR4      p\        \        \        P                  ! 4       R,          4      4      pRV P
                  RVRR/pV P                  '       d   RR	R
V P                  /VR&   RVRRVRV P                  R. RV P                  RVRV/./# )z0Build payload for flowMedia:batchGenerateImages.i ?B   	projectId	sessionIdtoolPINHOLEapplicationTypeRECAPTCHA_APPLICATION_TYPE_WEBri   recaptchaContextclientContextrequestsimageAspectRatioimageInputsimageModelNamer   r   )	randomrandintrT   inttimer2   r3   r7   r;   )rI   r   r   
session_id
client_ctxs   &&&  rL   _build_flow_body*GoogleFlowV2ImageProvider._build_flow_body   s    <>>&&1DTYY[4/01
 I


 !#C--.J)* Z#Z&(9(9!2$djjfD	
 	
rO   c               (    V ^8  d   QhRRRRRRRR/# rR   r   rT   output_pathr   r   r   rS   rU   )rV   s   "rL   rW   rX     s2     @ @@(,@4>@	@rO   c                l   V P                  WR7      p\        P                  V P                  R7      p\        P                  RV P                  V P                  V4       V P                  P                  WTV P                  4       R7      pV P                  V4       VP                  4        VP                  4       p\        P                  R\        VP!                  4       4      4       VP#                  R. 4      pV'       gD   \%        R\        VP!                  4       4       R\        P&                  ! V4      R	,           24      hV^ ,          p	V	P#                  R
/ 4      p
V
P#                  R4      ;'       g    V
P#                  R/ 4      pVP#                  R4      ;'       g    VP#                  RR4      pVP#                  R4      ;'       g    VP#                  RR4      pV'       g   \        P)                  R4       \%        R\        V	P!                  4       4       R\        V
P!                  4       4       RV'       d    \        VP!                  4       4       24      hR 24      hRV9  d   V R2MTp\        P                  R4       V P                  P#                  VRR/R7      pVP                  4        \+        VR4      ;_uu_ 4       pVP-                  VP.                  4       RRR4       Wn        \        P                  RV\3        VP.                  4      4       V#   + '       g   i     LB; i) z)Generate image via the Flow API endpoint.r   )r2   u3   Generating via Flow API  model=%s  aspect=%s → %sr   rc   zFlow response keys: %smediaz!No media in Flow response. Keys: z. Response: Ni  NimagegeneratedImagegenerated_imagefifeUrlfife_urlr$   mediaGenerationIdmedia_generation_idz,No fife_url found, trying alternate paths...z*No fife_url in Flow response. Media keys: z. Image keys: z. Generated keys: EMPTY=z=w1024z"Downloading image from FIFE URL...r   zhttps://labs.google/r   wbNz'Image saved: %s (%d bytes) via Flow API)r   FLOW_GENERATE_URLrV   r2   r@   rB   r;   r7   rH   postr   rj   r   r   rf   r   r   r5   r   dumpsrA   openwriter|   rE   len)rI   r   r   r   bodyurlr   result
media_listfirst_media
image_data	generatedr   media_idimg_urlimg_respfs   &&&&             rL   _generate_flow_sync-GoogleFlowV2ImageProvider._generate_flow_sync  s    $$V$7&&$//&BAJJ		
 {{8J8J8LM##D)-tFKKM/BC ZZ,
3D4G3H I!ZZ/568 
 !m __Wb1
NN#34 
 

r9
	 ==+LLy}}Z/L==!45 
 
!2:
 NNIJ<T+BRBRBT=U<V W#JOO$567 8#=F4	(8#9"TV  MT"TV  *-H)<XJf%(89;;??7Y@V4W?X!!#+t$$GGH$$% % '5  !	

  %$s   L##L3	c               (    V ^8  d   QhRRRRRRRR/# )	rR   r   rT   r   r   
num_imagesr   rS   r   rU   )rV   s   "rL   rW   rX   V  s,     
 

!+
@C
	
rO   c           	         Vf   \         P                  ! ^ R4      pRRVRV.RV/RRR\        \        P                  ! 4       R	,          4       2R
R/RRV P                  /RV P
                  /# )z)Build payload for v1:runImageFx (legacy).r   	userInputcandidatesCountpromptsr   r   r   rb   r   r   IMAGE_FX
modelInputmodelNameTypeaspectRatio)r   r   r   r   r;   r7   )rI   r   r   r   s   &&&&rL   _build_legacy_body,GoogleFlowV2ImageProvider._build_legacy_bodyV  s     <>>!V,D!:F8
 qTYY[4%7!8 9:
  4,,
 	
rO   c               (    V ^8  d   QhRRRRRRRR/# r   rU   )rV   s   "rL   rW   rX   l  s,     / //(,/4>/	/rO   c                0   V P                  WR7      p\        P                  RV P                  V P                  V4       V P
                  P                  \        W@P                  4       R7      pV P                  V4       VP                  4        VP                  4       pVP                  R4      ;'       g    . pV'       g*   \        R\        P                  ! V4      R,           24      hV^ ,          P                  R4      ;'       g    . pV'       g-   \        R\        V^ ,          P!                  4       4       24      hV^ ,          p	V	P                  R	4      p
V	P                  R
4      pV
'       g&   \        R\        V	P!                  4       4       24      h\"        P$                  ! V
4      p\'        VR4      ;_uu_ 4       pVP)                  V4       RRR4       Wn        \        P                  RV\-        V4      4       V#   + '       g   i     L8; i)z5Generate image via the legacy v1:runImageFx endpoint.r   u5   Generating via Legacy API  model=%s  aspect=%s → %sr   imagePanelsz"No imagePanels in response. Full: r   generatedImagesz No generatedImages. Panel keys: encodedImager   zNo encodedImage. Keys: r   Nz)Image saved: %s (%d bytes) via Legacy API)r   r@   rB   r;   r7   rH   r   LEGACY_GENERATE_URLr   rj   r   r   r5   r   r   r   r   base64	b64decoder   r   rE   r   )rI   r   r   r   r   r   r   panelsimagesfirst_imageencodedr   img_datar   s   &&&&          rL   _generate_legacy_sync/GoogleFlowV2ImageProvider._generate_legacy_syncl  s    &&v&9CJJ		
 {{d4F4F4H   
 	##D)M*00b4TZZ5G5M4NO  0177R24q	8H3I2JK  Qi//.1??#67!8k>N>N>P9Q8RSTT##G,+t$$GGH % '7c(m	
  %$s   HH	c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )rR   r   rT   r   
str | Pathr   r   r   r   rS   r   rU   )rV   s   "rL   rW   rX     sC     N NN  N 	N
 N 
NrO   c                   \        V4      pVP                  P                  RRR7       V P                  '       d    V P	                  WVR7      # V P                  WVR7      #   \
         dY   p\        P                  RT4       T P                  pRT n         T P                  YTR7      Y`n        u Rp?#   Y`n        i ; iRp?ii ; i)zQGenerate an image. Automatically selects Flow API or Legacy based on credentials.T)parentsexist_okr   z.Flow API failed: %s. Trying legacy fallback...r   N)
r   rr   mkdirr=   r   rz   r@   errorr;   r   )rI   r   r   r   r   r   	old_models   &&&&&  rL   _generate_sync(GoogleFlowV2ImageProvider._generate_sync  s     ;'   =
+//$/OO --f-MM  +MqQ JJ	)
+55fPT5U!*JJJ+s5   A" "C-)C B5)C /C5B==C  Cc               (    V ^8  d   QhRRRRRRRR/# )rR   r   rT   r   r   kwargsr   rS   rU   )rV   s   "rL   rW   rX     s2     	
 	
	
 	
 		

 
	
rO   c                b   "   \         P                  ! V P                  W3/ VB G Rj  xL
 #  L5i)z!Generate an image asynchronously.N)asyncio	to_threadr  )rI   r   r   r	  s   &&&,rL   generate"GoogleFlowV2ImageProvider.generate  s7      &&
8>
 
 	
 
s   &/-/c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )rR   r   rT   r   r   r   r   r   r   rS   ztuple[Path, str]rU   )rV   s   "rL   rW   rX     s<     ) ))  ) 	)
 ) 
)rO   c                B    V P                  WW4R7      pWPP                  3# )zEGenerate an image and return both the path and the mediaGenerationId.)r   r   )r  rE   )rI   r   r   r   r   paths   &&&&& rL   generate_with_media_id0GoogleFlowV2ImageProvider.generate_with_media_id  s/     ""d # 
 ((((rO   c                	:    V P                   P                  4        R # N)rH   closer[   s   &rL   r  GoogleFlowV2ImageProvider.close  s    rO   c                	    V # r  rU   r[   s   &rL   	__enter__#GoogleFlowV2ImageProvider.__enter__  s    rO   c                	&    V P                  4        R # r  )r  )rI   argss   &*rL   __exit__"GoogleFlowV2ImageProvider.__exit__  s    

rO   )rC   rE   rD   r=   r7   rH   r1   r;   r2   r3   r0   r  )N   )__name__
__module____qualname____firstlineno____doc__namerM   r\   rj   rg   r   r   r   r   r   r   r  r  r  r  r  r  __static_attributes__rU   rO   rL   r    r    S   sc    `D5Fv
	E.&"P

B@L
,/jN4	
)rO   r    ) r$  
__future__r   r  r   r   loggingr.   r   r   r   r   pathlibr   typingr   r   rF   providers.portsr   	getLoggerr   r@   r   r   r   r4   r8   r9   DEFAULT_FLOW_MODELr   r    rU   rO   rL   <module>r.     s   . #     	   '     )			8	$
 8p  J  -/) 
(=	 ,(
 !  #6&y	G GrO   