
    sj                       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 ddl	m
Z
 ddlmZ  ej        e          Zi Zded<   i Zd	ed
<    ej                    Zddd dZddd!dZddd"dZddd"dZddd#dZd$dZd%dZdS )&a  
Video Generation Provider Registry
==================================

Central map of registered providers. Populated by plugins at import-time via
``PluginContext.register_video_gen_provider()``; consumed by the
``video_generate`` tool to dispatch each call to the active backend.

Active selection
----------------
The active provider is chosen by ``video_gen.provider`` in ``config.yaml``.
If unset, :func:`get_active_provider` applies fallback logic:

1. If exactly one *available* provider is registered, use it.
2. Otherwise return ``None`` (the tool surfaces a helpful error pointing
   the user at ``hermes tools``).

Mirrors ``agent/image_gen_registry.py`` so the two surfaces behave the
same: the unconfigured fallback is filtered by ``is_available()`` so a box
that has credentials for only one backend (e.g. DeepInfra, while the
``fal``/``xai`` plugins also register unconditionally) auto-selects it
instead of returning ``None``.
    )annotationsN)DictListOptional)VideoGenProvider)hermes_home_keyzDict[str, VideoGenProvider]
_providersz&Dict[str, Dict[str, VideoGenProvider]]_scoped_providers)scopeproviderr   r   Optional[str]returnNonec                  t          | t                    s$t          dt          |           j                   | j        }t          |t                    r|                                st          d          |                                }t          5  |t          nt                              |i           }|                    |          }| ||<   ddd           n# 1 swxY w Y   |0t                              d|t          |          j                   dS t                              d|t          |           j                   dS )u   Register a video generation provider.

    Re-registration (same ``name``) overwrites the previous entry and logs
    a debug message — this makes hot-reload scenarios (tests, dev loops)
    behave predictably.
    z=register_provider() expects a VideoGenProvider instance, got z3Video gen provider .name must be a non-empty stringNz.Video gen provider '%s' re-registered (was %r)z'Registered video gen provider '%s' (%s))
isinstancer   	TypeErrortype__name__namestrstrip
ValueError_lockr	   r
   
setdefaultgetloggerdebug)r   r   raw_namer   targetexistings         </home/agent/.hermes/hermes-agent/agent/video_gen_registry.pyregister_providerr"   *   sy    h 011 
->>*- -
 
 	
 }Hh$$ PHNN,<,< PNOOO>>D	    $}2C2N2NuVX2Y2Y::d##t                              EtTRZ^^Mdeeeee>d8nnF]^^^^^s   ?CC#&C#List[VideoGenProvider]c                F   t           5  t          t                    }|                    t                              | pt                      i                      t          |                                          }ddd           n# 1 swxY w Y   t          |d           S )z0Return all registered providers, sorted by name.Nc                    | j         S N)r   )ps    r!   <lambda>z list_providers.<locals>.<lambda>J   s    qv     )key)
r   dictr	   updater
   r   r   listvaluessorted)r   mergeditemss      r!   list_providersr2   D   s    	 & &j!!'++E,F_5F5FKKLLLV]]__%%& & & & & & & & & & & & & & & %--....s   A2BB
B
r   r   Optional[VideoGenProvider]c               F   t          | t                    sdS t          5  |                                 }t                              |pt                      i                               |          pt                              |          cddd           S # 1 swxY w Y   dS )z5Return the provider registered under *name*, or None.N)r   r   r   r   r
   r   r   r	   )r   r   r*   s      r!   get_providerr5   M   s    dC   t	 e ejjll $$U%?o.?.?DDHHMMdQ[Q_Q_`cQdQde e e e e e e e e e e e e e e e e es   A*BBBc                   t           5  |t          nt                              |i           }|                    |                                           cd d d            S # 1 swxY w Y   d S r&   )r   r	   r
   r   r   )r   r   r   s      r!   snapshot_registrationr7   V   s     
 ( ($}2C2G2Gr2R2Rzz$**,,''( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   AA  A$'A$currentpreviousboolc               x   |                                  }t          5  |t          nt                              |i           }|                    |          |ur	 ddd           dS ||                    |d           n|||<   ||st                              |d           ddd           n# 1 swxY w Y   dS )zERestore a plugin registration only when *current* is still installed.NFT)r   r   r	   r
   r   r   pop)r   r8   r9   r   r*   r   s         r!   restore_registrationr=   ^   s    **,,C	 	/ 	/$}2C2N2NuVX2Y2Y::c??'))	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ JJsD!!!!"F3KV!!%...	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 4s   =B/&=B//B36B3c                   
 d} 	 ddl m}  |            }t          |t                    r|                    d          nd}t          |t                    rR|                    d          }t          |t
                    r(|                                r|                                } n2# t          $ r%}t          	                    d|           Y d}~nd}~ww xY w| r2	 ddl
m} |                                 |k    rd} n# t          $ r Y nw xY wt          5  t          t                    }|                    t                               t#                      i                      ddd           n# 1 swxY w Y   | r6|                    |           }||S t          	                    d	|            dS dd

fd|                                D             }	t'          |	          dk    r|	d         S dS )zResolve the currently-active provider.

    Reads ``video_gen.provider`` from config.yaml; falls back per the
    module docstring.
    Nr   )load_config_readonly	video_genr   z1Could not read video_gen.provider from config: %s)NOUS_MANAGED_PROVIDERfalzEvideo_gen.provider='%s' configured but not registered; failing closedr'   r   r   r:   c                    	 t          |                                           S # t          $ r,}t                              d| j        |           Y d}~dS d}~ww xY w)zDWrap ``is_available()`` so a buggy provider doesn't kill resolution.z.video_gen provider %s.is_available() raised %sNF)r:   is_available	Exceptionr   r   r   )r'   excs     r!   _is_available_safez/get_active_provider.<locals>._is_available_safe   se    	(())) 	 	 	LLI16SVWWW55555	s    # 
A!AAc                *    g | ]} |          |S  rI   ).0r'   rG   s     r!   
<listcomp>z'get_active_provider.<locals>.<listcomp>   s*    GGGq1C1CA1F1FGGGGr)      )r'   r   r   r:   )hermes_cli.configr?   r   r+   r   r   r   rE   r   r   tools.tool_backend_helpersrA   lowerr   r	   r,   r
   r   r.   len)
configuredr?   cfgsectionrawrF   rA   snapshotr   	availablerG   s             @r!   get_active_providerrW   t   s    !%J
O::::::""$$*4S$*?*?I#''+&&&Tgt$$ 	)++j))C#s## )		 ) YY[[
 O O OH#NNNNNNNNO  	HHHHHH!!%:::"
 	 	 	D	 
 F F
##)--o.?.?DDEEEF F F F F F F F F F F F F F F  <<
++OS	
 	
 	
 t    HGGGHOO--GGGI
9~~|4s=   B#B) )
C3CC C? ?
DDAE11E58E5c                     t           5  t                                           t                                           ddd           dS # 1 swxY w Y   dS )z"Clear the registry. **Test-only.**N)r   r	   clearr
   rI   r)   r!   _reset_for_testsrZ      s    	 " "!!!" " " " " " " " " " " " " " " " " "s   3AAA)r   r   r   r   r   r   )r   r   r   r#   )r   r   r   r   r   r3   )
r   r   r8   r   r9   r3   r   r   r   r:   )r   r3   )r   r   )__doc__
__future__r   logging	threadingtypingr   r   r   agent.video_gen_providerr   hermes_constantsr   	getLoggerr   r   r	   __annotations__r
   Lockr   r"   r2   r5   r7   r=   rW   rZ   rI   r)   r!   <module>re      s    0 # " " " " "      ' ' ' ' ' ' ' ' ' ' 5 5 5 5 5 5 , , , , , ,		8	$	$ +-
 , , , ,<>  > > > >	 MQ _ _ _ _ _ _4 .2 / / / / / / 7; e e e e e e *.( ( ( ( ( (       ,= = = =@" " " " " "r)   