
    i                     ^   U 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mZmZ  ej        e          Zdd	d
ddddddddddh ddd	ddddddddddddddddd h d!dd	d"d#d$d%dddddd&ddddd'h d(dd	d)d*d+d,d-d.d/d0ddddd1d2h d3dd	d4d5d6d7d8d9d:d;dd<ddd=h d>dd	d?d@dAdBddCddDdd<ddd=h dEdd	dFdGdHdIddddddJddKdLh dMdd	dNd*dOdPddddddQdih dRdd	dSdTdUdVddddddWdXdddYdZh d[dd	d\	Ze	ee	eef         f         ed]<   d^Zd_ZdZd`Z daZ!dZ"dbZ#dcZ$ddZ%deZ&dZ'dfZ( edgdhi          Z)da*da+ ej,                    Z-dj Z.dkedlefdmZ/ G dn do          Z0dp Z1dqedre	eef         fdsZ2dte3dle
e4         fduZ5dle6fdvZ7eddfdwedxed-edye
e4         dze
e	eef                  dle	eef         fd{Z8d|ed}edle
e	eef                  fd~Z9edddddfdxed-ede
e4         de
e:         de
e4         de
e         dye
e4         dlefdZ;dle<fdZ=dle<fdZ>edk    r e?d            e?d            e=            s, e?d            e?d            e?d            e@d           e?d           	 ddlZ e?d           n# eA$ r  e?d            e@d          w xY w e7            \  ZBZC e?deCD                    deB           deB d            e?deCD                    dd           deCD                    dd                       e?deCD                    d          rdnd             e?d           eE                                D ]O\  ZFZGeFeBk    rdndZH e?deFddeGD                    dd          ddeGD                    dd           eH            Pe)jI        r e?de)jJ                    ddlKmLZLmMZM ddddddd eNe          dedddxgddZOd ZPdxed-efdZQd ZR eLjS        ddeOeRe>g dd           dS )u  
Image Generation Tools Module

Provides image generation via FAL.ai. Multiple FAL models are supported and
selectable via ``hermes tools`` → Image Generation; the active model is
persisted to ``image_gen.model`` in ``config.yaml``.

Architecture:
- ``FAL_MODELS`` is a catalog of supported models with per-model metadata
  (size-style family, defaults, ``supports`` whitelist, upscaler flag).
- ``_build_fal_payload()`` translates the agent's unified inputs (prompt +
  aspect_ratio) into the model-specific payload and filters to the
  ``supports`` whitelist so models never receive rejected keys.
- Upscaling via FAL's Clarity Upscaler is gated per-model via the ``upscale``
  flag — on for FLUX 2 Pro (backward-compat), off for all faster/newer models
  where upscaling would either hurt latency or add marginal quality.

Pricing shown in UI strings is as-of the initial commit; we accept drift and
update when it's noticed.
    N)AnyDictOptionalUnion)	urlencode)DebugSession)resolve_managed_tool_gateway)fal_key_is_configuredmanaged_nous_tools_enabledprefers_gatewayzFLUX 2 Klein 9Bz<1szFast, crisp textz	$0.006/MPimage_size_presetlandscape_16_9	square_hdportrait_16_9)	landscapesquareportrait   pngF)num_inference_stepsoutput_formatenable_safety_checker>   seedprompt
image_sizer   r   r   )	displayspeed	strengthsprice
size_stylesizesdefaultssupportsupscalez
FLUX 2 Proz~6szStudio photorealismz$0.03/MP2   g      @   5T)r   guidance_scale
num_imagesr   r   safety_tolerance	sync_mode>
   r   r   r+   r   r)   r   r(   r*   r   r   zZ-Image Turboz~2szBilingual EN/CN, 6Bz	$0.005/MP   )r   r)   r   r   enable_prompt_expansion>   r   r   r   r)   r   r   r   r-   z$Nano Banana Pro (Gemini 3 Pro Image)z~8sz-Gemini 3 Pro, reasoning depth, text renderingz$0.15/image (1K)aspect_ratioz16:9z1:1z9:161K)r)   r   r*   
resolution>
   r   r   r+   r)   r0   r.   r   r*   enable_web_searchlimit_generationszGPT Image 1.5z~15szPrompt adherencez$0.034/imagegpt_literal	1536x1024	1024x1024	1024x1536medium)qualityr)   r   >   r   r8   r+   
backgroundr   r)   r   zGPT Image 2z~20sz3SOTA text rendering + CJK, world-aware photorealismu   $0.04–0.06/imagelandscape_4_3portrait_4_3>   r   r8   r+   r   r)   r   zIdeogram V3z~5szBest typographyz$0.03-0.09/imageBALANCEDAUTO)rendering_speedexpand_promptstyle>   r   r@   r   r   r?   r>   zRecraft V4 Proz'Design, brand systems, production-readyz$0.25/imager   >   colorsr   r   background_colorr   z
Qwen Imagez~12szLLM-based, complex textz$0.02/MP   g      @regular)r   r(   r)   r   acceleration>	   r   r   r+   r   r)   rE   r   r(   r   )	fal-ai/flux-2/klein/9bzfal-ai/flux-2-prozfal-ai/z-image/turbozfal-ai/nano-banana-prozfal-ai/gpt-image-1.5zfal-ai/gpt-image-2zfal-ai/ideogram/v3z#fal-ai/recraft/v4/pro/text-to-imagezfal-ai/qwen-image
FAL_MODELSrF   r   zfal-ai/clarity-upscaler   z"masterpiece, best quality, highresz.(worst quality, low quality, normal quality:2)gffffff?g333333?   image_toolsIMAGE_TOOLS_DEBUG)env_varc                  ^    t                      rt          d          sdS t          d          S )zsReturn managed fal-queue gateway config when the user prefers the gateway
    or direct FAL credentials are absent.	image_genNz	fal-queue)r
   r   r	        @/home/ubuntu/.hermes/hermes-agent/tools/image_generation_tool.py_resolve_managed_fal_gatewayrR   B  s4      {'C'C t'444rP   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)rS   normalized_origins     rQ   _normalize_fal_queue_url_formatr]   J  sW    ,23399;;BB3GG A?@@@""""rP   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.keyrS   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)r`   _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RuntimeErrorr]   _queue_url_format_sync_client_http_clientre   rf   _request_handle_class_add_hint_header_add_priority_header_add_timeout_header)selfr`   rS   sync_client_classclient_modules        rQ   __init__z_ManagedFalSyncClient.__init__T  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 .-rP   rV   N)pathhintwebhook_urlpriorityheadersstart_timeoutapplication	argumentsry   rz   r{   r|   r}   r~   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 )NrW   ?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timeoutr}   
request_idresponse_url
status_url
cancel_url)r   r   r   r   rc   )rn   lstripr   dictrr   rs   rm   rt   re   rp   rk   ro   rf   r   rq   )ru   r   r   ry   rz   r{   r|   r}   r~   urlrequest_headersresponsedatas                rQ   submitz_ManagedFalSyncClient.submitn  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)$ * 
 
 	
rP   )__name__
__module____qualname____doc__rX   rx   r   r   r   r   intfloatr   rO   rP   rQ   r_   r_   Q  s        ZZos oc o o o o> "%),059/
 /
 /
/
 S>/

 /
 sm/
 c]/
 /
 $sCx.)/
  c5j 12/
 /
 /
 /
 /
 /
rP   r_   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.rW   N)r`   rS   )gateway_originrZ   nous_user_token_managed_fal_client_lock_managed_fal_client_managed_fal_client_configr_   )managed_gatewayclient_configs     rQ   _get_managed_fal_clientr     s    
 	&--c22'M 
" 	# 	#*/I]/Z/Z&	# 	# 	# 	# 	# 	# 	# 	# 4/,;
 
 
 &3""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s   A?#A??BBmodelr   c                 z   dt          t          j                              i}t                      }|t	          j        | ||          S t          |          }	 |                    | ||          S # t          $ r>}t          |          }|'d|cxk    rdk     rn nt          d|  d| d          | d}~ww xY w)	zKSubmit a FAL request using direct credentials or the managed queue gateway.zx-idempotency-keyN)r   r}   i  i  z*Nous Subscription gateway rejected model 'z' (HTTP u   ). This model may not yet be enabled on the Nous Portal's FAL proxy. Either:
  • Set FAL_KEY in your environment to use FAL.ai directly, or
  • Pick a different model via `hermes tools` → Image Generation.)
rX   uuiduuid4rR   rl   r   r   	Exception_extract_http_statusr[   )r   r   r   r   managed_clientexcstatuss          rQ   _submit_fal_requestr     s   *C
,=,=>O244O )_UUUU,_==N$$# % 
 
 	

    
 &c**#"5"5"5"5#"5"5"5"5"5YU Y YY Y Y   	s   A2 2
B:<9B55B:r   c                     t          | dd          }|(t          |dd          }t          |t                    r|S t          | dd          }t          |t                    r|S dS )u   Return an HTTP status code from httpx/fal exceptions, else None.

    Defensive across exception shapes — httpx.HTTPStatusError exposes
    ``.response.status_code`` while fal_client wrappers may expose
    ``.status_code`` directly.
    r   Nstatus_code)rk   
isinstancer   )r   r   r   s      rQ   r   r     sp     sJ--H=$77fc"" 	MS-..F&# 4rP   c                     d} 	 ddl m}  |            }t          |t                    r|                    d          nd}t          |t                    r>|                    d          }t          |t
                    r|                                } n2# t          $ r%}t          	                    d|           Y d}~nd}~ww xY w| s't          j        dd                                          } | st          t          t                   fS | t          vr:t                              d	| t                     t          t          t                   fS | t          |          fS )
zResolve the active FAL model from config.yaml (primary) or default.

    Returns (model_id, metadata_dict). Falls back to DEFAULT_MODEL if the
    configured model is unknown (logged as a warning).
    rV   r   load_configrN   Nr   z.Could not load image_gen.model from config: %sFAL_IMAGE_MODELz4Unknown FAL model '%s' in config; falling back to %s)hermes_cli.configr   r   r   getrX   rY   r   loggerdebugosgetenvDEFAULT_MODELrG   warning)model_idr   cfgimg_cfgrawr   s         rQ   _resolve_fal_modelr     sf    H	L111111kmm*4S$*?*?I#''+&&&Tgt$$ 	'++g&&C#s## '99;; L L LEsKKKKKKKKL  <9.3399;; 8j777z!!Bm	
 	
 	
 j777Z)))s   BB 
CB>>Cr   r   r   	overridesc                 \   t           |          }|d         }|d         }|pt                                                                          }||vrt          }t	          |                    di                     }	|pd                                |	d<   |dv r||         |	d<   n$|dk    r||         |	d<   nt          d	|          |t          |t                    r||	d<   |r!|	                                D ]\  }
}|||	|
<   |d         fd|		                                D             S )a)  Build a FAL request payload for `model_id` from unified inputs.

    Translates aspect_ratio into the model's native size spec (preset enum,
    aspect-ratio enum, or GPT literal string), merges model defaults, applies
    caller overrides, then filters to the model's ``supports`` whitelist.
    r    r!   r"   rV   r   )r   r3   r   r.   zUnknown size_style: Nr   r#   c                 $    i | ]\  }}|v 	||S rO   rO   ).0kvr#   s      rQ   
<dictcomp>z&_build_fal_payload.<locals>.<dictcomp>3  s$    >>>TQXAqrP   )
rG   DEFAULT_ASPECT_RATIOlowerrY   r   r   r[   r   r   items)r   r   r.   r   r   metar    r!   aspectpayloadr   r   r#   s               @rQ   _build_fal_payloadr     sX    hDl#JME2299;;AACCFU%"488J#;#;<<G2,,..GH999 %f	~	%	%"'->
>>???JtS11 OO%% 	 	DAq}
JH>>>>W]]__>>>>rP   	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)zUpscale an image using FAL.ai's Clarity Upscaler.

    Returns upscaled image dict, or None on failure (caller falls back to
    the original image).
    z(Upscaling image with Clarity Upscaler...z, )	r   r   upscale_factornegative_prompt
creativityresemblancer(   r   r   r   imagez$Image upscaled successfully to %sx%swidthunknownheightr   r   T)r   r   r   upscaledr   z"Upscaler returned invalid responseNzError upscaling image: %sexc_info)r   infoUPSCALER_DEFAULT_PROMPTUPSCALER_FACTORUPSCALER_NEGATIVE_PROMPTUPSCALER_CREATIVITYUPSCALER_RESEMBLANCEUPSCALER_GUIDANCE_SCALEUPSCALER_NUM_INFERENCE_STEPSUPSCALER_SAFETY_CHECKERr   UPSCALER_MODELr   errorr   )r   r   upscaler_argumentshandlerresultupscaled_imagees          rQ   _upscale_imager   9  sr   %>??? #0EEOEE-7-/5#?%<

 

 &n@RSSS 	g''#G_NKK6""7I66""8Y77   &e,'++GQ77(,,Xq99 "1   	9:::t   0!dCCCttttts   D	D( D( (
E2EEr   r(   r)   r   c           	      	   t                      \  }}|| ||||||dddddd}	t          j                                        }
	 | r:t          | t                    r%t          |                                           dk    rt          d          t                      s2t                      s$d}t                      r|dz  }t          |          |pt                                                                          }|t          vr(t                              d	|t                     t          }i }|||d
<   |||d<   |||d<   |||d<   t!          || |||          }t                              d|                    d|          || dd                    t'          ||          }|                                }t          j                                        |
z
                                  }|rd|vrt          d          |                    dg           }|st          d          t+          |                    dd                    }g }|D ]}t          |t,                    rd|v s|d         |                    dd          |                    dd          d}|rZt/          |d         |                                           }|r|                    |           t                              d           d|d<   |                    |           |st          d          t3          d |D                       }t                              dt          |          |||           d |r|d         d         ndd!}d |	d"<   t          |          |	d#<   ||	d$<   t4                              d%|	           t4                                           t;          j        |d&d'          S # t>          $ r}t          j                                        |
z
                                  }d(t	          |           }t                               d)|d *           ddt	          |          tC          |          j"        d+}||	d,<   ||	d$<   t4                              d%|	           t4                                           t;          j        |d&d'          cY d}~S d}~ww xY w)-a  Generate an image from a text prompt using the configured FAL model.

    The agent-facing schema exposes only ``prompt`` and ``aspect_ratio``; the
    remaining kwargs are overrides for direct Python callers and are filtered
    per-model via the ``supports`` whitelist (unsupported overrides are
    silently dropped so legacy callers don't break when switching models).

    Returns a JSON string with ``{"success": bool, "image": url | None,
    "error": str, "error_type": str}``.
    )r   r.   r   r(   r)   r   r   NFr   )r   
parametersr   successimages_generatedgeneration_timez1Prompt is required and must be a non-empty stringz$FAL_KEY environment variable not setz' and managed FAL gateway is unavailablez-Invalid aspect_ratio '%s', defaulting to '%s'r   r(   r)   r   )r   r   u,   Generating image with %s (%s) — prompt: %sr   P   r   imagesu7   Invalid response from FAL.ai API — no images returnedzNo images were generatedr$   r   r   r   )r   r   r   z1Using original image as fallback (upscale failed)r   z%No valid image URLs returned from APIc              3   D   K   | ]}|                     d           dV  dS )r   r&   N)r   )r   imgs     rQ   	<genexpr>z&image_generate_tool.<locals>.<genexpr>  s3      RR3cggj>Q>QRQRRRRRRrP   z3Generated %s image(s) in %.1fs (%s upscaled) via %sT)r   r   r   r   r   image_generate_toolrH   )indentensure_asciizError generating image: z%sr   r   r   r   
error_typer   )#r   datetimenowr   rX   lenrY   r[   r
   rR   r   r   r   VALID_ASPECT_RATIOSr   r   r   r   r   r   total_secondsboolr   r   appendsum_debuglog_callsaver   dumpsr   r   typer   )r   r.   r   r(   r)   r   r   r   r   debug_call_data
start_timemessage	aspect_lcr   r   r   r   r   r   should_upscaleformatted_imagesr   original_imager   upscaled_countresponse_datar   	error_msgs                               rQ   r   r   j  sc   & ())NHd (#6,$*
 
  O" "&&((JnG 	RZ44 	RFLLNN8K8Kq8P8PPQQQ%'' 	&+G+I+I 	&<G)++ EDDW%%%!9%9@@BBHHJJ	///NN?2   -I$&	*/BI+,%*8I&'!&0Il#$)6Io&&fidi
 
 
	 	:HHY))8VCRC[	
 	
 	

 &h)DDD#,0022Z?NNPP 	X//VWWWHb)) 	97888dhhy%8899 	4 	4CsD)) esll5z!,,''(A.. N  T!/E
FLLNN!K!K! $++N;;;RSSS).N:&##N3333 	FDEEERR*:RRRRRA !!?NH	
 	
 	
 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    N&O) )
S3CSSSc                  T    t          t                      pt                                S )zDTrue if the FAL.ai API key (direct or managed gateway) is available.)r  r
   rR   rO   rP   rQ   check_fal_api_keyr    s#    %''I+G+I+IJJJrP   c                     	 t                      r	t           dS n# t          $ r Y nw xY w	 ddlm}  ddlm}  |              |             D ]*}	 |                                r dS # t          $ r Y 'w xY wn# t          $ r Y nw xY wdS )a  True if any image gen backend is available.

    Providers are considered in this order:

    1. The in-tree FAL backend (FAL_KEY or managed gateway).
    2. Any plugin-registered provider whose ``is_available()`` returns True.

    Plugins win only when the in-tree FAL path is NOT ready, which matches
    the historical behavior: shipping hermes with a FAL key configured
    should still expose the tool. The active selection among ready
    providers is resolved per-call by ``image_gen.provider``.
    Tr   )list_providers_ensure_plugins_discoveredF)	r  rl   ImportErroragent.image_gen_registryr  hermes_cli.pluginsr  is_availabler   )r  r  providers      rQ   #check_image_generation_requirementsr    s    	J4	    ;;;;;;AAAAAA""$$$&(( 	 	H((**  44    		     5sG    
''"A7 A&"A7 %A7 &
A30A7 2A33A7 7
BB__main__u:   🎨 Image Generation Tools — FAL.ai multi-model supportz<============================================================u(   ❌ FAL_KEY environment variable not setz-   Set it via: export FAL_KEY='your-key-here'z   Get a key: https://fal.ai/u   ✅ FAL.ai API key foundu    ✅ fal_client library availableu;   ❌ fal_client library not found — pip install fal-clientu   🤖 Active model: r   z ()z
   Speed: r   r   u     ·  Price: r   z   Upscaler: r$   onoffz
Available models:u    ← activerV   z  z<32z<6u%   
🐛 Debug mode enabled — session )registry
tool_errorimage_generatea3  Generate high-quality images from text prompts. The underlying backend (FAL, OpenAI, etc.) and model are user-configured and not selectable by the agent. Returns either a URL or an absolute file path in the `image` field; display it with markdown ![description](url-or-path) and the gateway will deliver it.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l m}   |             }t          |t                    r|                    d          nd}t          |t                    rR|                    d          }t          |t
                    r(|                                r|                                S n2# t          $ r%}t          	                    d|           Y d}~nd}~ww xY wdS )ui  Return the value of ``image_gen.provider`` from config.yaml, or None.

    We only consult the plugin registry when this is explicitly set — an
    unset value keeps users on the legacy in-tree FAL path even when other
    providers happen to be registered (e.g. a user has OPENAI_API_KEY set
    for other features but never asked for OpenAI image gen).
    r   r   rN   Nr  z%Could not read image_gen.provider: %s)
r   r   r   r   r   rX   rY   r   r   r   )r   r   sectionvaluer   s        rQ   _read_configured_image_providerr3  r  s    	C111111kmm*4S$*?*?I#''+&&&Tgt$$ 	%KK
++E%%% %%++-- %{{}}$ C C C<cBBBBBBBBC4s   B"B& &
C0CCc                 L   t                      }|r|dk    rdS 	 ddlm} ddlm}  |              ||          }n3# t
          $ r&}t                              d|           Y d}~dS d}~ww xY w|K	  |d            ||          }n2# t
          $ r%}t                              d	|           Y d}~nd}~ww xY w|t          j	        d
dd| ddd          S 	 |
                    | |          }np# t
          $ rc}t                              dt          |dd          |           t          j	        d
ddt          |dd           d| dd          cY d}~S d}~ww xY wt          |t                    st          j	        d
dddd          S t          j	        |          S )a  Route the call to a plugin-registered provider when one is selected.

    Returns a JSON string on dispatch, or ``None`` to fall through to the
    built-in FAL path.

    Dispatch only fires when ``image_gen.provider`` is explicitly set AND
    it does not point to ``fal`` (FAL still lives in-tree in this PR;
    a later PR ports it into ``plugins/image_gen/fal/``). Any other value
    that matches a registered plugin provider wins.
    falNr   )get_providerr  z%image_gen plugin dispatch skipped: %sT)forcez*image_gen plugin force-refresh skipped: %sFzimage_gen.provider='zk' is set but no plugin registered that name. Run `hermes plugins list` to see available image gen backends.provider_not_registeredr   r,  z"Image gen provider '%s' raised: %sr/  r   z
Provider 'z	' error: provider_exceptionz#Provider returned a non-dict resultprovider_contract)r3  r  r6  r  r  r   r   r   r   r  generater   rk   r   r   )r   r.   
configuredr6  r  r  r   r   s           rQ   _dispatch_to_plugin_providerr=    s    122J u,,t
 	:99999AAAAAA""$$$<
++   <cBBBttttt 	L '&T2222#|J//HH 	L 	L 	LLLEsKKKKKKKK	L z1z 1 1 1 4	
 	
 	 	 		""&|"LL 
 
 
0Hfc**C	
 	
 	
 zP'(FC"@"@PP3PP.	
 
   	 	 	 	 	 	
 fd## z:-	
 
   	 :fsL   !< 
A,A''A,2B
 

B9B44B9C4 4
E!>AEE!E!c                     |                      dd          }|st          d          S |                      dt                    }t          ||          }||S t	          ||          S )Nr   rV   z'prompt is required for image generationr.   r,  )r   r%  r   r=  r   )argskwr   r.   
dispatcheds        rQ   _handle_image_generaterB    s{    XXh##F ECDDD88N,@AAL .flCCJ!   rP   rN   u   🎨)r/  toolsetschemar   check_fnrequires_envis_asyncemoji)Tr   r   loggingr   r   	threadingr   typingr   r   r   r   urllib.parser   rl   tools.debug_helpersr   tools.managed_tool_gatewayr	   tools.tool_backend_helpersr
   r   r   	getLoggerr   r   rG   rX   __annotations__r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   Lockr   rR   r]   r_   r   r   BaseExceptionr   r   tupler   r   r   r   r   r  r  r  print
SystemExitr  r   r   r   r   midmmarkeractive
session_idtools.registryr$  r%  listIMAGE_GENERATE_SCHEMAr3  r=  rB  registerrO   rP   rQ   <module>r`     s
    *   				       - - - - - - - - - - - - " " " " " "     , , , , , , C C C C C C          
	8	$	$4 %'))!'
 
 $%"%*
 


 
 
 ) .  *))!'
 
 $&!"%* #
 

 
 

 3 8 #*))!'
 
 $%"%*',
 

 
 

 / 4 :D#$
 
 " # 
 

 
 

 1 6 #'#$!#
 
  "
 

 
 
 - 2 !J% *(!&
 
  "
 

 
 
 = B !&#))!'
 
  *!
 


 
 
 ) . $>))!'
 
 $U

 
 
 ', ,,  .))!'
 
 $&!"%
 

 
 
 - Q`) `)
Dd38n$% ` ` `F )" 9  + > K    !  
m-@	A	A	A ! )9>++ 5 5 5#c #c # # # #L
 L
 L
 L
 L
 L
 L
 L
^# # #(s tCH~    >m     * *E  *  *  *  *L -*.(? (?(?(? (? 3-	(?
 S#X'(? 
#s(^(? (? (? (?\+c +C +HT#s(^<T + + + +f -)-&* $#'VG VGVGVG "#VG UO	VG
 VG C=VG 3-VG 	VG VG VG VGrK4 K K K K
#T # # # #R z	E
FGGG	E(OOO 8999=>>>-...jmm	E
$%%%01111   KLLLjmm ('))NHd	E
LH = =
L
L
L
L
LMMM	E
Ttxx--
T
TDHHWc<R<R
T
TUUU	E
B$((9"5"5@$$5
B
BCCC	E
   ""$$ W WQ"%//rU3UUUaeeGS11UUUgs8K8KUVUUVVVV} LJv7HJJKKK 0 / / / / / / / 	G  !k 
 !011  N/	 
 
 J   8  *E EC E E E EP  $  	 "0
	 	 	 	 	 	s   J' 'K