
    i&                        U d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
 ddlmZmZmZmZmZmZ  ej        e          ZdZddd	d
ddddddddddddZded<   dZddddZd%dZd&d Z G d! d"e          Zd'd$ZdS )(u  OpenAI image generation backend.

Exposes OpenAI's ``gpt-image-2`` model at three quality tiers as an
:class:`ImageGenProvider` implementation. The tiers are implemented as
three virtual model IDs so the ``hermes tools`` model picker and the
``image_gen.model`` config key behave like any other multi-model backend:

    gpt-image-2-low     ~15s   fastest, good for iteration
    gpt-image-2-medium  ~40s   default — balanced
    gpt-image-2-high    ~2min  slowest, highest fidelity

All three hit the same underlying API model (``gpt-image-2``) with a
different ``quality`` parameter. Output is base64 JSON → saved under
``$HERMES_HOME/cache/images/``.

Selection precedence (first hit wins):

1. ``OPENAI_IMAGE_MODEL`` env var (escape hatch for scripts / tests)
2. ``image_gen.openai.model`` in ``config.yaml``
3. ``image_gen.model`` in ``config.yaml`` (when it's one of our tier IDs)
4. :data:`DEFAULT_MODEL` — ``gpt-image-2-medium``
    )annotationsN)AnyDictListOptionalTuple)DEFAULT_ASPECT_RATIOImageGenProvidererror_responseresolve_aspect_ratiosave_b64_imagesuccess_responsezgpt-image-2zGPT Image 2 (Low)z~15szFast iteration, lowest costlow)displayspeed	strengthsqualityzGPT Image 2 (Medium)z~40su   Balanced — defaultmediumzGPT Image 2 (High)z~2minz,Highest fidelity, strongest prompt adherencehigh)zgpt-image-2-lowgpt-image-2-mediumzgpt-image-2-highzDict[str, Dict[str, Any]]_MODELSr   	1536x1024	1024x1024	1024x1536)	landscapesquareportraitreturnDict[str, Any]c                    	 ddl m}   |             }t          |t                    r|                    d          nd}t          |t                    r|ni S # t
          $ r'}t                              d|           i cY d}~S d}~ww xY w)z@Read ``image_gen`` from config.yaml (returns {} on any failure).r   )load_config	image_genNz#Could not load image_gen config: %s)hermes_cli.configr!   
isinstancedictget	Exceptionloggerdebug)r!   cfgsectionexcs       F/home/ubuntu/.hermes/hermes-agent/plugins/image_gen/openai/__init__.py_load_openai_configr.   R   s    111111kmm*4S$*?*?I#''+&&&T$Wd33;ww;   :C@@@						s   AA 
B!B=BBTuple[str, Dict[str, Any]]c                 h   t           j                            d          } | r| t          v r| t          |          fS t	                      }t          |                    d          t                    r|                    d          ni }d}t          |t                    r5|                    d          }t          |t                    r|t          v r|}|5|                    d          }t          |t                    r|t          v r|}||t          |         fS t          t          t                   fS )z9Decide which tier to use and return ``(model_id, meta)``.OPENAI_IMAGE_MODELopenaiNmodel)	osenvironr&   r   r.   r$   r%   strDEFAULT_MODEL)env_overrider*   
openai_cfg	candidatevaluetops         r-   _resolve_modelr=   _   s   :>>"677L 3//W\222


C&01B1BD&I&IQ"""rJ#I*d## w''eS!! 	ew&6&6Igggc3 	C7NNI'),,,'-000    c                  n    e Zd ZdZedd            Zedd            ZddZdd	ZddZ	ddZ
efddZdS )OpenAIImageGenProvideruF   OpenAI ``images.generate`` backend — gpt-image-2 at low/medium/high.r   r6   c                    dS )Nr2    selfs    r-   namezOpenAIImageGenProvider.name       xr>   c                    dS )NOpenAIrB   rC   s    r-   display_namez#OpenAIImageGenProvider.display_name   rF   r>   boolc                v    t           j                            d          sdS 	 dd l}n# t          $ r Y dS w xY wdS )NOPENAI_API_KEYFr   T)r4   r5   r&   r2   ImportError)rD   r2   s     r-   is_availablez#OpenAIImageGenProvider.is_available   sU    z~~.// 	5	MMMM 	 	 	55	ts   ( 
66List[Dict[str, Any]]c                H    d t                                           D             S )Nc                H    g | ]\  }}||d          |d         |d         dd S )r   r   r   varies)idr   r   r   pricerB   ).0model_idmetas      r-   
<listcomp>z6OpenAIImageGenProvider.list_models.<locals>.<listcomp>   sQ     	
 	
 	
 $ 	?g!+.! 	
 	
 	
r>   )r   itemsrC   s    r-   list_modelsz"OpenAIImageGenProvider.list_models   s-    	
 	
 #*--//	
 	
 	
 		
r>   Optional[str]c                    t           S )N)r7   rC   s    r-   default_modelz$OpenAIImageGenProvider.default_model   s    r>   r   c                    dddddddgdS )	NrH   paidz,gpt-image-2 at low/medium/high quality tiersrL   zOpenAI API keyz$https://platform.openai.com/api-keys)keyprompturl)rE   badgetagenv_varsrB   rC   s    r-   get_setup_schemaz'OpenAIImageGenProvider.get_setup_schema   s4    A ,.A 	
 
 	
r>   ra   aspect_ratiokwargsr   c           	        |pd                                 }t          |          }|st          ddd|          S t          j                            d          st          ddd|          S 	 d	d l}n## t          $ r t          d
dd|          cY S w xY wt                      \  }}t                              |t          d                   }t          ||d|d         d}		 |                                }
 |
j        j        d#i |	}nK# t          $ r>}t                              dd           t          d| dd|||          cY d }~S d }~ww xY wt#          |dd           pg }|st          ddd|||          S |d	         }t#          |dd           }t#          |dd           }t#          |dd           }|rU	 t%          |d|           }n/# t          $ r"}t          d| dd|||          cY d }~S d }~ww xY wt'          |          }n|r|}nt          d dd|||          S ||d         d!}|r||d<   t)          ||||d|"          S )$N z1Prompt is required and must be a non-empty stringinvalid_argumentr2   )error
error_typeproviderrg   rL   uz   OPENAI_API_KEY not set. Run `hermes tools` → Image Generation → OpenAI to configure, or `hermes setup` to add the key.auth_requiredr   z8openai Python package not installed (pip install openai)missing_dependencyr      r   )r3   ra   sizenr   zOpenAI image generation failedT)exc_infoz OpenAI image generation failed: 	api_error)rl   rm   rn   r3   ra   rg   datazOpenAI returned no image dataempty_responseb64_jsonrb   revised_promptopenai_)prefixzCould not save image to cache: io_errorz2OpenAI response contained neither b64_json nor URL)rr   r   )imager3   ra   rg   rn   extrarB   )stripr   r   r4   r5   r&   r2   rM   r=   _SIZES	API_MODELrH   imagesgenerater'   r(   r)   getattrr   r6   r   )rD   ra   rg   rh   aspectr2   tier_idrW   rr   payloadclientresponser,   rv   firstb64rb   ry   
saved_path	image_refr~   s                        r-   r   zOpenAIImageGenProvider.generate   s    ,B%%''%l33 	!I-!#	    z~~.// 
	!& +!#	 	 	 		MMMM 	 	 	!P/!#	     	 '((zz&&"233
 I#
 #
	]]__F-v}-8888HH 		 		 		LL9DLIII!>>>&!#        		 x..4" 	!5+!#    QeZ..eUD)) (8$?? 	
+C8K'8K8KLLL

   %ACAA)%!!!'         JII 	 II!J+!#    *.$y/ J J 	5&4E"#
 
 
 	
sN   .A3 3BB!&D 
E3EEE;G 
G<G71G<7G<N)r   r6   )r   rJ   )r   rO   )r   r[   r   r   )ra   r6   rg   r6   rh   r   r   r   )__name__
__module____qualname____doc__propertyrE   rI   rN   rZ   r]   rf   r	   r   rB   r>   r-   r@   r@   |   s        PP   X    X   

 

 

 

   
 
 
 
" 1x
 x
 x
 x
 x
 x
 x
r>   r@   Nonec                H    |                      t                                 dS )uI   Plugin entry point — wire ``OpenAIImageGenProvider`` into the registry.N)register_image_gen_providerr@   )ctxs    r-   registerr   -  s#    ##$:$<$<=====r>   r   )r   r/   )r   r   )r   
__future__r   loggingr4   typingr   r   r   r   r   agent.image_gen_providerr	   r
   r   r   r   r   	getLoggerr   r(   r   r   __annotations__r7   r   r.   r=   r@   r   rB   r>   r-   <module>r      s    . # " " " " "  				 3 3 3 3 3 3 3 3 3 3 3 3 3 3                
	8	$	$ 	 '2	  *+	  (C	 & &    * % 
 

 
 
 
1 1 1 1:i
 i
 i
 i
 i
- i
 i
 i
b> > > > > >r>   