
    Jj*                        U d Z ddlmZ ddlZddlZddlmZ ddlmZ dZ	dZ
dd	d
ddd
gZded<   ddd
Zded<   d7dZd8dZd9dZd:dZd;dZd<d!Zd=d#Zd=d$Zd>d'Zd?d@d*ZdAd,Zd@d-ZdBdCd0ZdDd3ZdBdEd5ZdFd6ZdS )Gz:Mixture-of-Agents configuration and slash-command helpers.    )annotationsN)deepcopy)Any__HERMES_MOA_TURN_V1__defaultzopenai-codexzgpt-5.5providermodel
openrouterzdeepseek/deepseek-v4-prozlist[dict[str, str]]DEFAULT_MOA_REFERENCE_MODELSzanthropic/claude-opus-4.8zdict[str, str]DEFAULT_MOA_AGGREGATORvaluer   returnfloat | Nonec                f    | | dk    rdS 	 t          |           S # t          t          f$ r Y dS w xY w)uF  Coerce to a float, or None when unset/blank/invalid.

    Used for optional sampling params (reference_temperature /
    aggregator_temperature) where None means 'don't send the parameter —
    provider default applies', matching how a single-model Hermes agent
    never sends temperature unless explicitly configured.
    N )float	TypeError
ValueError)r   s    ;/home/rurouni/.hermes/hermes-agent/hermes_cli/moa_config.py_coerce_float_or_noner      sN     }tU||z"   tts    00intc                    | | dk    r|S 	 t          |           S # t          t          f$ r; 	 t          t          |                     cY S # t          t          f$ r |cY cY S w xY ww xY w)Nr   r   r   r   r   )r   r   s     r   _coerce_intr   (   s    }5zzz"   	uU||$$$$$:& 	 	 	NNNNN	s,    A'AA'A#A'"A##A'
int | Nonec                    | | dk    rdS 	 t          |           }nN# t          t          f$ r: 	 t          t          |                     }n# t          t          f$ r Y Y dS w xY wY nw xY w|dk    r|ndS )u   Coerce to a positive int, or None when unset/blank/invalid/non-positive.

    Used for optional caps (e.g. reference_max_tokens) where None means
    'no cap' — the safe default that preserves prior uncapped behavior.
    Nr   r   r   )r   ns     r   _coerce_int_or_noner   4   s     }tJJz"   	E%LL!!AA:& 	 	 	444	 A
 A114s2    A'A
A'A!A' A!!A'&A'strc                |    t          | pd                                                                          }|dv r|ndS )zCNormalize the fan-out cadence; unknown values fall back to default.r   >   	user_turnper_iterationr#   )r    striplower)r   modes     r   _coerce_fanoutr'   F   s@    u{!!##))++D99944N    slotdict[str, str] | Nonec                R   t          | t                    sd S t          |                     d          pd                                          }t          |                     d          pd                                          }|r|sd S |                                dk    rd S ||dS )Nr	   r   r
   moar   )
isinstancedictr    getr$   r%   )r)   r	   r
   s      r   _clean_slotr0   L   s    dD!! t488J''-2..4466H!!'R((..00E 5 t ~~5  t 5111r(   dict[str, Any]c            	     `    t          t                    t          t                    d d dd dddS )N   r#   T)reference_models
aggregatorreference_temperatureaggregator_temperature
max_tokensreference_max_tokensfanoutenabled)r   r   r    r(   r   _default_presetr=   ]   s=    $%ABB566 "&"& $!  r(   rawc                   t          | t                    si } |                     d          }t          |t                    st          |t                    r|gng }d |D             }d |D             }|st	          t
                    }t          |                     d                    pt	          t                    }t          |                     dd                    ||t          |                     d                    t          |                     d                    t          |                     d	          d
          t          |                     d                    t          |                     d                    dS )Nr4   c                ,    g | ]}t          |          S r<   )r0   .0items     r   
<listcomp>z%_normalize_preset.<locals>.<listcomp>v   s     333$K333r(   c                    g | ]}||S Nr<   rA   s     r   rD   z%_normalize_preset.<locals>.<listcomp>w   s    666TT%5D%5%5%5r(   r5   r;   Tr6   r7   r8   r3   r9   r:   )r;   r4   r5   r6   r7   r8   r9   r:   )r-   r.   r/   listr   r   r0   r   boolr   r   r   r'   )r>   raw_refsrefsr5   s       r   _normalize_presetrK   l   si   c4   ww)**Hh%% D ",Hd!;!;CH::33(333D66T666D 6455SWW\2233Wx@V7W7WJ 	40011  !6sww?V7W7W!X!X"7@X8Y8Y"Z"Z!#'',"7"7>> !4CGG<R4S4S T T !!2!233-  r(   c                   t          | t                    si } |                     d          }i }t          |t                    rQ|                                D ]<\  }}t	          |pd                                          }|rt          |          ||<   =|st          |           |t          <   t	          |                     d          pd                                          }|r||vr"t          t          |          t                    }||vrt                      ||<   t	          |                     d          pd                                          }||vrd}||         }|||t          |d                   t          |d                   |d         |d         |d	         |                    d
          |                    dd          |d         dS )zReturn validated MoA config with named presets.

    Backward compatible with the first PR shape where ``moa`` itself contained
    ``reference_models`` and ``aggregator`` directly.
    presetsr   default_presetactive_presetr4   r5   r6   r7   r8   r9   r:   r#   r;   )rN   rO   rM   r4   r5   r6   r7   r8   r9   r:   r;   )r-   r.   r/   itemsr    r$   rK   DEFAULT_MOA_PRESET_NAMEnextiterr=   r   )	r>   presets_rawrM   namepreset
clean_namedefault_nameactive_nameactives	            r   normalize_moa_configr[      s    c4   '')$$K)+G+t$$ @'--// 	@ 	@LD&TZR..00J @&7&?&?
#  B+<S+A+A'(sww/006B77==??L D<w66DMM+BCC7"" / 1 1cggo..4"55;;==K'!!\"F&$$V,>%?@@vl344!'(?!@"()A"B\* &

+A B B**X77)$  r(   config	list[str]c                n    t          |           }t          |d                                                   S )NrM   )r[   rG   keys)r\   cfgs     r   list_moa_presetsra      s-    
v
&
&CI##%%&&&r(   rU   
str | Nonec                   t          |           }t          |p|                    d          pt                                                    }|d                             |          }|t          |          t          |          S )NrN   rM   )r[   r    r/   rQ   r$   KeyErrorr   )r\   rU   r`   preset_namerV   s        r   resolve_moa_presetrf      sx    
v
&
&CdRcgg&677R;RSSYY[[K^,,F~{###Fr(   textc                    t          |pd                                          }|sdS t          |           }|d                             |          }||                    dd          sdS |S )a  Return the preset name iff ``text`` exactly matches an *enabled* preset.

    Used by the no-explicit-provider switch path (PATH B in
    ``hermes_cli/model_switch.py``) to recognize a bare ``/model <preset>``
    that the user typed without the ``moa:`` prefix. This is an *implicit*
    match, so it must honor the per-preset ``enabled`` opt-out: a user who set
    ``enabled: false`` to disable a preset must not have a plain model switch
    whose name happens to collide with that preset key silently pivot the
    session onto the MoA virtual provider (issue #55187). Explicit selection
    via ``--provider moa`` / the model picker does not go through here, so a
    disabled preset is still reachable when the user explicitly asks for it.
    r   NrM   r;   T)r    r$   r[   r/   )r\   rg   wantedr`   rV   s        r   exact_moa_preset_namerj      sq     __""$$F t
v
&
&C^''F~VZZ	488~tMr(   c                    t          |           }t          |pd                                          }|r||d         vrt          |          ||d<   |S )Nr   rM   rO   )r[   r    r$   rd   )r\   rU   r`   cleans       r   set_active_moa_presetrm      s[    
v
&
&C
OO!!##E c)n,,uoo CJr(   promptrV   c                    t          | pd          t          |pi |          d}t          j        t	          j        |dd                              d                                        d          }t           | S )zBEncode a /moa one-shot turn for frontends that can only send text.r   )rn   r\   ),:F)
separatorsensure_asciiutf-8ascii)	r    rf   base64urlsafe_b64encodejsondumpsencodedecodeMOA_MARKER_PREFIX)rn   r\   rV   payloadencodeds        r   encode_moa_turnr      s     fl##$V\r6:: G &
7zFFFMMgVV fWoo   ****r(   message!tuple[str, dict[str, Any] | None]c                   t          | t                    r|                     t                    s| dfS | t	          t                    d                                         }	 t          j        t          j	        |
                    d                                        d                    }n# t          $ r | dfcY S w xY wt          |                    d          pd          }|t          |                    d          pi           fS )z%Decode a hidden /moa one-shot marker.Nru   rt   rn   r   r\   )r-   r    
startswithr|   lenr$   rx   loadsrv   urlsafe_b64decoderz   r{   	Exceptionr/   rK   )r   r~   r}   rn   s       r   decode_moa_turnr     s   gs## 7+=+=>O+P+P }c+,,--.4466G*V5gnnW6M6MNNUUV]^^__   }X&&,"--F$W[[%:%:%@bAAAAs   #AB0 0C Cuser_promptc                &    t          | ||          S )z>Build the hidden one-shot payload used by TUI/gateway routing.)rV   )r   )r   r\   rV   s      r   build_moa_turn_promptr     s    ;v>>>>r(   c                     dS )NzUsage: /moa <prompt>  (runs one prompt through the default MoA preset, then restores your model; pick a preset from the model picker to switch for the session)r<   r<   r(   r   	moa_usager     s     m  mr(   )r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r    )r)   r   r   r*   )r   r1   )r>   r   r   r1   )r\   r   r   r]   rF   )r\   r   rU   rb   r   r1   )r\   r   rg   r    r   rb   )NN)rn   r    r\   r   rV   rb   r   r    )r   r   r   r   )r   r    r\   r   rV   rb   r   r    )r   r    )__doc__
__future__r   rv   rx   copyr   typingr   r|   rQ   r   __annotations__r   r   r   r   r'   r0   r=   rK   r[   ra   rf   rj   rm   r   r   r   r   r<   r(   r   <module>r      s)   @ @ @ " " " " " "              , #   )44(BCC6      (* *         	 	 	 	       $O O O O2 2 2 2"   ( ( ( (V- - - -`' ' ' '
       .   	+ 	+ 	+ 	+ 	+
B 
B 
B 
B? ? ? ? ?
m m m m m mr(   