
    Fije(                       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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save_url_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/   S   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   r7   c                    dS )Nr3    selfs    r.   namezOpenAIImageGenProvider.name       xr?   c                    dS )NOpenAIrC   rD   s    r.   display_namez#OpenAIImageGenProvider.display_name   rG   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)r5   r6   r'   r3   ImportError)rE   r3   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   pricerC   ).0model_idmetas      r.   
<listcomp>z6OpenAIImageGenProvider.list_models.<locals>.<listcomp>   sQ     	
 	
 	
 $ 	?g!+.! 	
 	
 	
r?   )r   itemsrD   s    r.   list_modelsz"OpenAIImageGenProvider.list_models   s-    	
 	
 #*--//	
 	
 	
 		
r?   Optional[str]c                    t           S )N)r8   rD   s    r.   default_modelz$OpenAIImageGenProvider.default_model   s    r?   r    c                    dddddddgdS )	NrI   paidz,gpt-image-2 at low/medium/high quality tiersrM   zOpenAI API keyz$https://platform.openai.com/api-keys)keyprompturl)rF   badgetagenv_varsrC   rD   s    r.   get_setup_schemaz'OpenAIImageGenProvider.get_setup_schema   s4    A ,.A 	
 
 	
r?   rb   aspect_ratiokwargsr   c           	     N   |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'          |          }nq|rZ	 t)          |d|           }t'          |          }nJ# t          $ r(}t                              d ||           |}Y d }~nd }~ww xY wt          d!dd|||          S ||d         d"}|r||d<   t-          ||||d|#          S )%N z1Prompt is required and must be a non-empty stringinvalid_argumentr3   )error
error_typeproviderrh   rM   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   )r4   rb   sizenr   zOpenAI image generation failedT)exc_infoz OpenAI image generation failed: 	api_error)rm   rn   ro   r4   rb   rh   datazOpenAI returned no image dataempty_responseb64_jsonrc   revised_promptopenai_)prefixzCould not save image to cache: io_errorzGOpenAI image URL %s could not be cached (%s); falling back to bare URL.z2OpenAI response contained neither b64_json nor URL)rs   r   )imager4   rb   rh   ro   extrarC   )stripr   r   r5   r6   r'   r3   rN   r>   _SIZES	API_MODELrI   imagesgenerater(   r)   r*   getattrr   r7   r   warningr   )rE   rb   rh   ri   aspectr3   tier_idrX   rs   payloadclientresponser-   rw   firstb64rc   rz   
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 	

,+C8K'8K8KLLL
  
OO		       ]  
  						  "J+!#    *.$y/ J J 	5&4E"#
 
 
 	
sf   .A3 3BB!&D 
E3EEE;G 
G<G71G<7G<H6 6
I( I##I(N)r   r7   )r   rK   )r   rP   )r   r\   r   r    )rb   r7   rh   r7   ri   r   r   r    )__name__
__module____qualname____doc__propertyrF   rJ   rO   r[   r^   rg   r	   r   rC   r?   r.   rA   rA   }   s        PP   X    X   

 

 

 

   
 
 
 
" 1D
 D
 D
 D
 D
 D
 D
r?   rA   Nonec                H    |                      t                                 dS )uI   Plugin entry point — wire ``OpenAIImageGenProvider`` into the registry.N)register_image_gen_providerrA   )ctxs    r.   registerr   :  s#    ##$:$<$<=====r?   r   )r   r0   )r   r   )r   
__future__r   loggingr5   typingr   r   r   r   r   agent.image_gen_providerr	   r
   r   r   r   r   r   	getLoggerr   r)   r   r   __annotations__r8   r   r/   r>   rA   r   rC   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:u
 u
 u
 u
 u
- u
 u
 u
z> > > > > >r?   