
    Kik                        d Z ddlZddlZddlZddlZddlZddlZddlmZm	Z	m
Z
mZ ddlmZ ddlZddlmZ ddlmZ ddlmZ  ej        e          ZdZd	Zd
ZdZdZdZdZdZddddZ  e!e "                                          Z#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,g dZ-ddgZ.g dZ/ edd !          Z0da1da2 ej3                    Z4d" Z5d#e6d$e6fd%Z7 G d& d'          Z8d( Z9d)e6d*ee6e	f         fd+Z:	 d}d-ee6ee6e;f         f         d.e;d/e<d0e;d1e6d2e6d$ee6e	f         fd3Z=d4e6d5e6d$ee6e	f         fd6Z>eeeeedfd7e6d8e6d.e;d/e<d0e;d1e6d9e
e;         d$e6fd:Z?d$e@fd;ZAd$e@fd<ZBd$ee6e	f         fd=ZCed>k    rL	  eDd?            eDd@            eA            ZEeEs- eDdA            eDdB            eDdC            eFd           n eDdD           	 ddlZ eDdE           n,# eG$ r$  eDdF            eDdG            eFd           Y nw xY w eDdH            eDdIe             eDdJe$ dKe% dL           e0jH        r( eDdMe0jI                     eDdNe0jI         dO           n eDdP            eDdQ            eDdR            eDdS            eDdT            eDdU            eDdV            eDdW            eDdX            eDdY            eDdZ            eDd[            eDd\            eDd]            eDd^           e-D ]ZJ eDd_eJ             eDd`            eDda           e/D ]ZK eDd_eK             eDdb            eDdc            eDdd            eDde            eDdf            eDdg            eDdh            eDdi            eDdj            eDdk            eDdl           ddmlLmMZM dndodpdqdrdsdqg ddtd	dudvd7gdwdxZNdy ZO eMjP        dndzeNeOeBg dd{|           dS )~a  
Image Generation Tools Module

This module provides image generation tools using FAL.ai's FLUX 2 Pro model with 
automatic upscaling via FAL.ai's Clarity Upscaler for enhanced image quality.

Available tools:
- image_generate_tool: Generate images from text prompts with automatic upscaling

Features:
- High-quality image generation using FLUX 2 Pro model
- Automatic 2x upscaling using Clarity Upscaler for enhanced quality
- Comprehensive parameter control (size, steps, guidance, etc.)
- Proper error handling and validation with fallback to original images
- Debug logging support
- Sync mode for immediate results

Usage:
    from image_generation_tool import image_generate_tool
    import asyncio
    
    # Generate and automatically upscale an image
    result = await image_generate_tool(
        prompt="A serene mountain landscape with cherry blossoms",
        image_size="landscape_4_3",
        num_images=1
    )
    N)DictAnyOptionalUnion)	urlencode)DebugSession)resolve_managed_tool_gateway)managed_nous_tools_enabledzfal-ai/flux-2-pro	landscape2         @   pngF5landscape_16_9	square_hdportrait_16_9)r   squareportraitzfal-ai/clarity-upscaler   z"masterpiece, best quality, highresz.(worst quality, low quality, normal quality:2)gffffff?g333333?      )r   r   portrait_4_3r   landscape_4_3r   jpeg)noneregularhighimage_toolsIMAGE_TOOLS_DEBUG)env_varc                  L    t          j        d          rdS t          d          S )zOReturn managed fal-queue gateway config when direct FAL credentials are absent.FAL_KEYNz	fal-queue)osgetenvr	        8/home/ubuntu/hermes-agent/tools/image_generation_tool.py_resolve_managed_fal_gatewayr)   Z   s'    	y t'444r'   queue_run_originreturnc                     t          | pd                                                              d          }|st          d          | dS )N /z$Managed FAL queue origin is required)strstriprstrip
ValueError)r*   normalized_origins     r(   _normalize_fal_queue_url_formatr4   a   sW    ,23399;;BB3GG A?@@@""""r'   c                       e Zd ZdZdedefdZdddddddded	eeef         d
edee         dee         dedeeeef                  dee	e
ef                  fdZdS )_ManagedFalSyncClientzPSmall per-instance wrapper around fal_client.SyncClient for managed queue hosts.keyr*   c                   t          t          dd           }|t          d          t          t          dd           }|t          d          t          |          | _         ||          | _        t          | j        dd           | _        t          |dd           | _        t          |dd           | _        t          |d	d           | _	        t          |d
d           | _
        t          |dd           | _        t          |dd           | _        | j        t          d          | j        | j        t          d          | j	        t          d          d S )N
SyncClientz>fal_client.SyncClient is required for managed FAL gateway modeclientz:fal_client.client is required for managed FAL gateway mode)r7   _client_maybe_retry_request_raise_for_statusSyncRequestHandleadd_hint_headeradd_priority_headeradd_timeout_headerzFfal_client.SyncClient._client is required for managed FAL gateway modezKfal_client.client request helpers are required for managed FAL gateway modezLfal_client.client.SyncRequestHandle is required for managed FAL gateway mode)getattr
fal_clientRuntimeErrorr4   _queue_url_format_sync_client_http_clientr<   r=   _request_handle_class_add_hint_header_add_priority_header_add_timeout_header)selfr7   r*   sync_client_classclient_modules        r(   __init__z_ManagedFalSyncClient.__init__k   sg   #JdCC$_```
Hd;; [\\\!@AQ!R!R--#666#D$5y$GG$+M;QSW$X$X!!(8KT!R!R%,]<OQU%V%V" '7H$ O O$+M;PRV$W$W!#*=:NPT#U#U $ghhh$,0F0Nlmmm%-mnnn .-r'   r-   N)pathhintwebhook_urlpriorityheadersstart_timeoutapplication	argumentsrP   rQ   rR   rS   rT   rU   c                   | j         |z   }	|r|	d|                    d          z   z  }	||	dt          d|i          z   z  }	t          |pi           }
|| j        |                     ||
           |,| j        t          d          |                     ||
           |,| j        t          d          |                     ||
           |                     | j	        d|	|t          | j        dd          |
	          }|                     |           |                                }|                     |d
         |d         |d         |d         | j	                  S )Nr.   ?fal_webhookzGfal_client.client.add_priority_header is required for priority requestszEfal_client.client.add_timeout_header is required for timeout requestsPOSTdefault_timeoutg      ^@)jsontimeoutrT   
request_idresponse_url
status_url
cancel_url)r_   r`   ra   rb   r:   )rE   lstripr   dictrI   rJ   rD   rK   r<   rG   rB   rF   r=   r]   rH   )rL   rV   rW   rP   rQ   rR   rS   rT   rU   urlrequest_headersresponsedatas                r(   submitz_ManagedFalSyncClient.submit   s    ${2 	*3S))))C"3M;#?@@@@Cw}"-- 5 A!!$888(0"#lmmm%%h@@@$'/"#jkkk$$]ODDD,,D-/@%HH# - 
 
 	x(((}}))L)n-L)L)$ * 
 
 	
r'   )__name__
__module____qualname____doc__r/   rO   r   r   r   r   intfloatri   r&   r'   r(   r6   r6   h   s        ZZos oc o o o o> "%),059/
 /
 /
/
 S>/

 /
 sm/
 c]/
 /
 $sCx.)/
  c5j 12/
 /
 /
 /
 /
 /
r'   r6   c                    | j                             d          | j        f}t          5  t          t
          |k    rt          cddd           S t          | j        | j                   a|at          cddd           S # 1 swxY w Y   dS )zQReuse the managed FAL client so its internal httpx.Client is not leaked per call.r.   N)r7   r*   )gateway_originr1   nous_user_token_managed_fal_client_lock_managed_fal_client_managed_fal_client_configr6   )managed_gatewayclient_configs     r(   _get_managed_fal_clientrx      s    
 	&--c22'M 
" 	# 	#*/I]/Z/Z&	# 	# 	# 	# 	# 	# 	# 	# 4/,;
 
 
 &3""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s   A?#A??BBmodelrW   c                     dt          t          j                              i}t                      }|t	          j        | ||          S t          |          }|                    | ||          S )zKSubmit a FAL request using direct credentials or the managed queue gateway.zx-idempotency-keyN)rW   rT   )r/   uuiduuid4r)   rC   ri   rx   )ry   rW   rf   rv   managed_clients        r(   _submit_fal_requestr~      sv    *C
,=,=>O244O )_UUUU,_==N   !   r'   r   
image_sizenum_inference_stepsguidance_scale
num_imagesoutput_formataccelerationc                 4   i }t          | t                    r)| t          vrt          d|  dt                     | |d<   nt          | t                    rd| vsd| vrt          d          t          | d         t
                    rt          | d         t
                    st          d          | d         dk     s| d         dk     rt          d	          | d         d
k    s| d         d
k    rt          d          | |d<   nt          d          t          |t
                    r|dk     s|dk    rt          d          ||d<   t          |t
          t          f          r|dk     s|dk    rt          d          t          |          |d<   t          |t
                    r|dk     s|dk    rt          d          ||d<   |t          vrt          d| dt                     ||d<   |t          vrt          d| dt                     ||d<   |S )a1  
    Validate and normalize image generation parameters for FLUX 2 Pro model.
    
    Args:
        image_size: Either a preset string or custom size dict
        num_inference_steps: Number of inference steps
        guidance_scale: Guidance scale value
        num_images: Number of images to generate
        output_format: Output format for images
        acceleration: Acceleration mode for generation speed
    
    Returns:
        Dict[str, Any]: Validated and normalized parameters
    
    Raises:
        ValueError: If any parameter is invalid
    zInvalid image_size 'z'. Must be one of: r   widthheightz8Custom image_size must contain 'width' and 'height' keysz3Custom image_size width and height must be integers@   z3Custom image_size dimensions must be at least 64x64i   z6Custom image_size dimensions must not exceed 2048x2048zEimage_size must be either a preset string or a dict with width/heightr   d   z8num_inference_steps must be an integer between 1 and 100r   g?g      4@z4guidance_scale must be a number between 0.1 and 20.0r   r   z-num_images must be an integer between 1 and 4r   zInvalid output_format 'r   zInvalid acceleration 'r   )	
isinstancer/   VALID_IMAGE_SIZESr2   rd   rn   ro   VALID_OUTPUT_FORMATSVALID_ACCELERATION_MODES)r   r   r   r   r   r   	validateds          r(   _validate_parametersr      s   2 I *c"" b...fJffSdffggg",	,	J	%	% b*$$
(B(BWXXX*W-s33 	T:jQYFZ\_;`;` 	TRSSSg##z(';b'@'@RSSSg%%H)=)D)DUVVV",	,`aaa )3// U3F3J3JNadgNgNgSTTT':I#$ nsEl33 Q~7K7K~`dOdOdOPPP"'"7"7I j#&& J*q..JNNHIII(Il 000k=kkUikklll!.Io 333m,mmSkmmnnn ,Inr'   	image_urloriginal_promptc           
         	 t                               d           | t           d| t          t          t
          t          t          t          t          d	}t          t          |          }|                                }|rd|v r|d         }t                               d|                    dd          |                    d	d                     |d
         |                    dd          |                    d	d          dt          dS t                               d           dS # t          $ r(}t                               d|d           Y d}~dS d}~ww xY w)a  
    Upscale an image using FAL.ai's Clarity Upscaler.
    
    Uses the synchronous fal_client API to avoid event loop lifecycle issues
    when called from threaded contexts (e.g. gateway thread pool).
    
    Args:
        image_url (str): URL of the image to upscale
        original_prompt (str): Original prompt used to generate the image
    
    Returns:
        Dict[str, Any]: Upscaled image data or None if upscaling fails
    z(Upscaling image with Clarity Upscaler...z, )	r   promptupscale_factornegative_prompt
creativityresemblancer   r   enable_safety_checkerrW   imagez$Image upscaled successfully to %sx%sr   unknownr   re   r   T)re   r   r   upscaledr   z"Upscaler returned invalid responseNzError upscaling image: %sexc_info)loggerinfoUPSCALER_DEFAULT_PROMPTUPSCALER_FACTORUPSCALER_NEGATIVE_PROMPTUPSCALER_CREATIVITYUPSCALER_RESEMBLANCEUPSCALER_GUIDANCE_SCALEUPSCALER_NUM_INFERENCE_STEPSUPSCALER_SAFETY_CHECKERr~   UPSCALER_MODELgeterror	Exception)r   r   upscaler_argumentshandlerresultupscaled_imagees          r(   _upscale_imager   #  s   ,>??? #0EEOEE-7-/5#?%<

 

  &(
 
 
  	g''#G_NKK>@R@RSZ\e@f@fhvhzhz  |D  FO  iP  iP  Q  Q  Q%e,'++GQ77(,,Xq99 "1   LL=>>>4   0!dCCCttttts   D	D( D( (
E2EEr   aspect_ratioseedc           
         |r&|                                                                 nt          }|t          vr(t                              d|t                     t          }t          |         }| |||||||dddddd}	t          j                                        }
	 t                              d|| dd                    | r:t          | t                    r%t          |                                           dk    rt          d	          t          j        d
          s2t                      s$d}t!                      r|dz  }t          |          t#          |||||d          }|                                 |d         |d         |d         |d         |d         t$          t&          dd	}|t          |t(                    r||d<   t                              d           t                              dt*                     t                              d||           t                              d|d                    t                              d|d                    t-          t*          |          }|                                }t          j                                        |
z
                                  }|rd|vrt          d          |                    dg           }|st          d          g }|D ]}t          |t2                    rd|v r|d         |                    d d          |                    d!d          d"}t5          |d         |                                           }|r|                    |           t                              d#           d|d$<   |                    |           |st          d%          t9          d& |D                       }t                              d't          |          ||           d|r|d         d         ndd(}d|	d)<   t          |          |	d*<   ||	d+<   t:                              d,|	           t:                                           tA          j!        |d-d.          S # tD          $ r}t          j                                        |
z
                                  }d/t          |           }t          #                    d0|d1           ddt          |          tI          |          j%        d2}||	d3<   ||	d+<   t:                              d,|	           t:                                           tA          j!        |d-d.          cY d}~S d}~ww xY w)4a  
    Generate images from text prompts using FAL.ai's FLUX 2 Pro model with automatic upscaling.
    
    Uses the synchronous fal_client API to avoid event loop lifecycle issues.
    The async API's global httpx.AsyncClient (cached via @cached_property) breaks
    when asyncio.run() destroys and recreates event loops between calls, which
    happens in the gateway's thread-pool pattern.
    
    Args:
        prompt (str): The text prompt describing the desired image
        aspect_ratio (str): Image aspect ratio - "landscape", "square", or "portrait" (default: "landscape")
        num_inference_steps (int): Number of denoising steps (1-50, default: 50)
        guidance_scale (float): How closely to follow prompt (0.1-20.0, default: 4.5)
        num_images (int): Number of images to generate (1-4, default: 1)
        output_format (str): Image format "jpeg" or "png" (default: "png")
        seed (Optional[int]): Random seed for reproducible results (optional)
    
    Returns:
        str: JSON string containing minimal generation results:
             {
                 "success": bool,
                 "image": str or None  # URL of the upscaled image, or None if failed
             }
    z-Invalid aspect_ratio '%s', defaulting to '%s')r   r   r   r   r   r   r   r   NFr   )
parametersr   successimages_generatedgeneration_timez*Generating %s image(s) with FLUX 2 Pro: %sP   z1Prompt is required and must be a non-empty stringr#   z$FAL_KEY environment variable not setz' and managed FAL gateway is unavailabler   r   r   r   r   r   T)	r   r   r   r   r   r   r   safety_tolerance	sync_moder   z5Submitting generation request to FAL.ai FLUX 2 Pro...z  Model: %sz  Aspect Ratio: %s -> %sz  Steps: %sz  Guidance: %sr   imagesz5Invalid response from FAL.ai API - no images returnedzNo images were generatedre   r   r   )re   r   r   z Using original image as fallbackr   z%No valid image URLs returned from APIc              3   F   K   | ]}|                     d d          dV  dS )r   Fr   N)r   ).0imgs     r(   	<genexpr>z&image_generate_tool.<locals>.<genexpr>  s6      YY3cggjRW>X>XYQYYYYYYr'   z,Generated %s image(s) in %.1fs (%s upscaled))r   r   r   r   r   image_generate_toolr   )indentensure_asciizError generating image: z%sr   )r   r   r   
error_typer   )&lowerr0   DEFAULT_ASPECT_RATIOASPECT_RATIO_MAPr   warningdatetimenowr   r   r/   lenr2   r$   r%   r)   r
   r   ENABLE_SAFETY_CHECKERSAFETY_TOLERANCErn   DEFAULT_MODELr~   r   total_secondsrd   r   appendsum_debuglog_callsaver]   dumpsr   r   typerj   )r   r   r   r   r   r   r   aspect_ratio_lowerr   debug_call_data
start_timemessagevalidated_paramsrW   r   r   r   r   formatted_imagesr   original_imager   upscaled_countresponse_datar   	error_msgs                             r(   r   r   `  s   D :F_++--33555K_!111FVjkkk1!"45J ($#6,$*	
 	
  O" "&&((J{G@*fUXVXUXkZZZ  	RZ44 	RFLLNN8K8Kq8P8PPQQQ 	)$$ 	&(D(F(F 	&<G)++ EDDW%%% 0+^ZX^
 
 llnn*<8#34I#J./?@*<8-o>%: 0

 

	 
4 5 5 $IfKLLLM=111.0BJOOOM#34I#JKKK$&67G&HIII &
 
 
 #,0022Z?NNPP  	V//TUUUHb)) 	97888  	< 	<C#t$$ <#u: WWWa00!ggh22" " "0E
FLLNN!K!K! <$++N;;;; NN#EFFF16N:.$++N;;; 	FDEEEYY*:YYYYYBCHXDYDY[jlz{{{ 3CM%a(//
 

 &*	".12B.C.C*+-<)* 	-???z-FFFF G G G#,0022Z?NNPP7s1vv77	T9t444 VVq''*	
 
 $- -<)*-???z-FFFFFFFFF%Gs    O3R 
VCU>8V>Vc                  `    t          t          j        d          pt                                S )z
    Check if the FAL.ai API key is available in environment variables.
    
    Returns:
        bool: True if API key is set, False otherwise
    r#   )boolr$   r%   r)   r&   r'   r(   check_fal_api_keyr     s(     	)$$F(D(F(FGGGr'   c                  R    	 t                      sdS ddl} dS # t          $ r Y dS w xY w)z
    Check if all requirements for image generation tools are met.
    
    Returns:
        bool: True if requirements are met, False otherwise
    Fr   NT)r   rC   ImportError)rC   s    r(   #check_image_generation_requirementsr   #  sO    
 "" 	5 	t   uus     
&&c                  4    t                                           S )z
    Get information about the current debug session.
    
    Returns:
        Dict[str, Any]: Dictionary containing debug session information
    )r   get_session_infor&   r'   r(   get_debug_session_infor   7  s     ""$$$r'   __main__u@   🎨 Image Generation Tools Module - FLUX 2 Pro + Auto Upscalingz<============================================================u(   ❌ FAL_KEY environment variable not setz7Please set your API key: export FAL_KEY='your-key-here'zGet API key at: https://fal.ai/u   ✅ FAL.ai API key foundu    ✅ fal_client library availableu    ❌ fal_client library not foundz&Please install: pip install fal-clientu-   🛠️ Image generation tools ready for use!u   🤖 Using model: u   🔍 Auto-upscaling with: z (zx)u&   🐛 Debug mode ENABLED - Session ID: z9   Debug logs will be saved to: ./logs/image_tools_debug_z.jsonu?   🐛 Debug mode disabled (set IMAGE_TOOLS_DEBUG=true to enable)z
Basic usage:z7  from image_generation_tool import image_generate_toolz  import asyncior-   z  async def main():z2      # Generate image with automatic 2x upscalingz)      result = await image_generate_tool(zD          prompt='A serene mountain landscape with cherry blossoms',z%          image_size='landscape_4_3',z          num_images=1z      )z      print(result)z  asyncio.run(main())z
Supported image sizes:z  - z5  - Custom: {'width': 512, 'height': 768} (if needed)z
Acceleration modes:z
Example prompts:zH  - 'A candid street photo of a woman with a pink bob and bold eyeliner'zE  - 'Modern architecture building with glass facade, sunset lighting'z=  - 'Abstract art with vibrant colors and geometric patterns'z?  - 'Portrait of a wise old owl perched on ancient tree branch'z;  - 'Futuristic cityscape with flying cars and neon lights'z
Debug mode:z  # Enable debug loggingz  export IMAGE_TOOLS_DEBUG=truez=  # Debug logs capture all image generation calls and resultsz5  # Logs saved to: ./logs/image_tools_debug_UUID.json)registryimage_generatea  Generate high-quality images from text prompts using FLUX 2 Pro model with automatic 2x upscaling. Creates detailed, artistic images that are automatically upscaled for hi-rez results. Returns a single upscaled image URL. Display it using markdown: ![description](URL)objectstringzJThe text prompt describing the desired image. Be detailed and descriptive.)r   descriptionzlThe aspect ratio of the generated image. 'landscape' is 16:9 wide, 'portrait' is 16:9 tall, 'square' is 1:1.)r   enumr   default)r   r   )r   
propertiesrequired)namer   r   c           	          |                      dd          }|st          j        ddi          S t          ||                      dd          ddd	d
d           S )Nr   r-   r   z'prompt is required for image generationr   r   r   r   r   r   )r   r   r   r   r   r   r   )r   r]   r   r   )argskwr   s      r(   _handle_image_generater     sn    XXh##F Pz7$MNOOOXXnk::   r'   	image_genu   🎨)r   toolsetschemar   check_fnrequires_envis_asyncemoji)r   )Qrm   r]   loggingr$   r   	threadingr{   typingr   r   r   r   urllib.parser   rC   tools.debug_helpersr   tools.managed_tool_gatewayr	   tools.tool_backend_helpersr
   	getLoggerrj   r   r   r   DEFAULT_NUM_INFERENCE_STEPSDEFAULT_GUIDANCE_SCALEDEFAULT_NUM_IMAGESDEFAULT_OUTPUT_FORMATr   r   r   listkeysVALID_ASPECT_RATIOSr   r   r   r   r   r   r   r   r   r   r   r   r   rt   ru   Lockrs   r)   r/   r4   r6   rx   r~   rn   ro   r   r   r   r   r   r   r   printapi_availableexitr   active
session_idsizemodetools.registryr   IMAGE_GENERATE_SCHEMAr   registerr&   r'   r(   <module>r     s   :   				       - - - - - - - - - - - - " " " " " "     , , , , , , C C C C C C A A A A A A		8	$	$ $"          "  
 d+002233  + > K    !      666 	m-@	A	A	A ! )9>++ 5 5 5#c #c # # # #L
 L
 L
 L
 L
 L
 L
 L
^# # #(s tCH~    * F Fc4S>)*FF F 	F
 F F 
#s(^F F F FR:c :C :DcN : : : :~ -:2(.vG vGvGvG vG 	vG
 vG vG 3-vG 	vG vG vG vGrH4 H H H HT    (%S#X % % % % z 
E
LMMM	E(OOO &%''M *8999GHHH/000Q()))01111   01116777Q
 
E
9:::	E
.}
.
.///	E
L~
L
L
L
L
LMMM } QJv7HJJKKKb&J[bbbccccOPPP	E
	E
CDDD	E
	E"III	E
   	E
>???	E
5666	E
PQQQ	E
1222	E
"###	E)	E
   	E
!"""	E
$%%%!  mTmm	E
ABBB	E
!"""(  mTmm	E
	E
TUUU	E
QRRR	E
IJJJ	E
KLLL	E
GHHH	E/	E
$%%%	E
+,,,	E
IJJJ	E
ABBB $ # # # # #  b !k 
 !;;;  N&	 
 
 J   ,    	 "0
	 	 	 	 	 	s   G &HH