
    Jj                       d Z ddlmZ ddlZddlZddlZddlmZ ddd)dZd*dZ	d+dZ
d,dZd+dZd-dZd+dZd+dddZd+dZd-dZd Zd+dZd Zd+dZd+dZd+d Zd+d!Zd+d"Zd+d#Zd+d$Zd.d&Zd+d'Zd+d(ZdS )/uw  Per-provider model-selection wizard flows for ``hermes setup`` / ``hermes model``.

Extracted from ``hermes_cli/main.py`` as part of the god-file decomposition
campaign (``~/.hermes/plans/god-file-decomposition.md``, Phase 2 — splitting
main.py handler/flow bodies out of the module). These 18 ``_model_flow_*``
functions are the interactive provider-setup branches dispatched by
``select_provider_and_model`` (which stays in main.py).

Behavior-neutral: each function is lifted verbatim. ``select_provider_and_model``
in main.py re-imports them (``from hermes_cli.model_setup_flows import *``-style
explicit import) so existing call sites — and test monkeypatches that target
``hermes_cli.main._model_flow_*`` — keep resolving against main.py's namespace.

main.py-internal helpers the flows call (``_prompt_api_key``, ``_save_custom_provider``,
the reasoning-effort/stepfun/qwen helpers, ``_run_anthropic_oauth_flow``, …) are
imported lazily inside the flows (``from hermes_cli.main import ...`` resolves at
call time, when main.py is fully loaded) so this module never imports
``hermes_cli.main`` at import time -> no import cycle.
    )annotationsN) clear_model_endpoint_credentials provider_namebase_urlstrr   returnNonec                  	 ddl m}m} ddlm}m}  || |pd          }|sdS  |d          }t          |t                    sdS |                                D ]\  }}	t          |t                    r0|
                    |          r||k    st          |	t                    sKg }
g }d}|	D ]}t          |t                    rU|                    d          dk    r<d	}|                    d
          }|r"|                    t          |                     l|
                    |           |r |||
|           dS # t          $ r Y dS w xY w)ab  Drop stale ``model_config`` credentials from inactive custom pools.

    ``model_config`` means "the credential currently stored under
    ``model.api_key``". After an explicit custom-endpoint switch, any old
    custom pool still carrying that source points at the previous endpoint and
    can be selected before the freshly saved config is tried.
    r   )CUSTOM_POOL_PREFIXget_custom_provider_pool_key)read_credential_poolwrite_credential_poolNr   Fsourcemodel_configTid)removed_ids)agent.credential_poolr   r   hermes_cli.authr   r   
isinstancedictitemsr	   
startswithlistgetappend	Exception)r   r   r   r   r   r   active_pool_keypoolspool_keyentriesretainedr   changedentryentry_ids                  B/home/rurouni/.hermes/hermes-agent/hermes_cli/model_setup_flows.py/_prune_replaced_custom_model_config_credentialsr(      s   &	
 	
 	
 	
 	
 	
 	
 	
 	POOOOOOO66'/4
 
 
  	F$$T**%&& 	F!& 	S 	SHgx--**+=>> ..!'400 / HKG  ' 'eT** uyy/B/Bn/T/T"G$yyH :#**3x==999&&&& S%%hkRRRR)	S 	S*    s   !E  E C:E 
EEtitlec           	        g d}	 ddl m}  || |d          }|dk    rt                       d|         S n# t          $ r Y nw xY wt          |            t	          |d          D ]'\  }}|dk    rdnd}t          d| d| d	|            (t                       	 t          d
                                          }n# t          t          f$ r d}Y nw xY w|dk    rdS |dk    rdS dS )zPrompt for reuse / reauthenticate / cancel with the standard radio UI.

    Returns one of ``"use"``, ``"reauth"``, ``"cancel"``. Falls back to a
    numbered prompt when curses is unavailable (piped stdin, non-TTY).
    )zUse existing credentialsz Reauthenticate (new OAuth login)Cancelr   _curses_prompt_choice)usereauthcancel      →   .   Choice [1/2/3]: 12r/   3r0   r.   )	hermes_cli.setupr-   printr   	enumerateinputstripKeyboardInterruptEOFError)r)   choicesr-   idxilabelmarkerchoices           r'   _prompt_auth_credentials_choicerG   S   s]     G
::::::##E7A66!88GGG.s33      
%LLLgq)) * *5q&&c(6((A(((())))	GGG+,,2244x(    }}x}}x5s!   .6 
AA!B> >CCc                   ddl m} ddlm} ddlm}m}m}m} ddl	m
}  |dddd	
          }	 |d          pd}
|
st          d           t                        ||	|
d          \  }}|rdS ddlm}m}  |d          } |dd          } ||||d||p|
          }|r ||           ddl	m}m}  |            }|                    d          }t%          |t&                    s|rd|ini }||d<   d|d<   ||d<   d|d<   t)          |d            ||            |             t          d| d           dS t          d           dS ) z5OpenRouter provider: ensure API key, then pick model.r   _prompt_api_key)OPENROUTER_BASE_URL)ProviderConfig_prompt_model_selection_save_model_choicedeactivate_provider)get_env_value
openrouter
OpenRouterapi_key)OPENROUTER_API_KEY)r   name	auth_typeapi_key_env_varsrT   r   z&Get one at: https://openrouter.ai/keysprovider_idN)	model_idsget_pricing_for_providerTforce_refresh)current_modelpricingconfirm_providerconfirm_base_urlconfirm_api_keyload_configsave_configmodeldefaultproviderr   chat_completionsapi_modeFclear_api_modeDefault model set to: z (via OpenRouter)
No change.)hermes_cli.mainrJ   hermes_constantsrK   r   rL   rM   rN   rO   hermes_cli.configrP   r;   hermes_cli.modelsrZ   r[   rd   re   r   r   r   r   )configr^   rJ   rK   rL   rM   rN   rO   rP   pconfigexisting_key	_resolvedabortrZ   r[   openrouter_modelsr_   selectedrd   re   cfgrf   s                         r'   _model_flow_openrouterr{   y   sm   //////444444            0///// n0	  G !=!566<"L 6777&w,WWWIu EEEEEEEE!	555 '&|4HHHG&&#%,!1\  H  8$$$ 	?>>>>>>>kmm  %&& 	!*/7Y&&RE CL(j/j.j(uEEEECBxBBBCCCCCl    rU   presetr   c                   t          d|             t          d           t          |                    d          pg d          D ]C\  }}t          d| d|                    d           d	|                    d
                      D|                    d          pi }t          d|                    d           d	|                    d
                      dS )zDPrint the full reference-models + aggregator breakdown for a preset.z
  Preset: z  Reference models:reference_modelsr1   start    r5   rh   :rf   
aggregatorz  Aggregator:  N)r;   r<   r   )rU   r}   rB   slotaggs        r'   _print_moa_presetr      s    	
t

	
   vzz*<==C1MMM H H	TFSFFDHHZ00FF488G3D3DFFGGGG
**\
"
"
(bC	
DCGGJ//
D
D#'''2B2B
D
DEEEEEr|   c           
     2   ddl m}m} ddlm}m} ddlm}  |t          | t                    r| 
                    d          ni           }|
                    d          pi }|st          d           dS t          |                                          }	|
                    d	          p|	d         }
g }|	D ]}||         
                    d
          pi }|r-|
                    d           d|
                    d           nd}t          ||         
                    d          pg           }||
k    rdnd}|                    | d| d| d|            |
|	v r|	                    |
          nd}	 ddlm}  |d||          }n# t&          $ r t          d           t)          |d          D ]*\  }}|dz
  |k    rdnd}t          d| d| d|            +	 t+          dt          |           d                                          }n(# t.          t0          f$ r t          d           Y Y dS w xY w|s|}na	 t3          dt5          t          |          dz
  t7          |          dz
                      }n!# t8          $ r t          d           Y Y dS w xY wY nw xY w||dk     rt          d           dS |	|         }||         } |            }|
                    d          }t          |t                    s|rd|ini }||d<   ||d<   d|d<   t;          |d            |                    d!d            ||            ||            |             t                       t          d"| d#           t?          ||           dS )$u  Mixture of Agents virtual provider: pick a preset, then persist it.

    Unlike the other provider flows there is no credential step — MoA is a
    virtual provider whose presets reference already-configured providers. We
    always show the preset list (even when there is only one) so the user sees
    what they are selecting, then print the full preset breakdown on selection.
    r   rN   rO   rc   )normalize_moa_configmoapresetszCNo MoA presets configured. Run `hermes moa configure <name>` first.Ndefault_presetr   rh   r   rf   r   r   u     ← defaultz  (agg , z refs)r,   z"Select a Mixture of Agents preset:r1   r2   r3   r4   r5   z  Choice [1-]: rn   rg   Trk   r   rm   z (via Mixture of Agents)) r   rN   rO   rq   rd   re   hermes_cli.moa_configr   r   r   r   r;   r   keyslenr   indexr:   r-   r   r<   r=   r>   r?   r@   maxminint
ValueErrorr   popr   )rs   r^   rN   rO   rd   re   r   r   r   namesdefault_namerowsnr   	agg_label	ref_countsuffixdefault_idxr-   rB   rC   rowrE   rawselected_namer}   rz   rf   s                               r'   _model_flow_moar      s    HGGGGGGG::::::::::::::

Jvt4L4LTvzz%000RT
U
UCggi  &BG STTT  E77+,,8aL D I Iqz~~l++1rCFNswwz**??SWWW-=-=???B	
'9::@bAA	$%$5$52qGGGGiGGvGGHHHH/;u/D/D%++l+++!K::::::##$H$P[\\   2333a(( 	, 	,FAs 1u44UU#F*v****S**++++	5s4yy55566<<>>CC!8, 	 	 	,FFF	  	CC!STQC1==>>   l###& {cAggl#JM]#F
+--CGGGEeT"" &+3E""G$E)E*
 %U4@@@@	IIj$K}%%%	GGG	
J=
J
J
JKKKmV,,,,,s[   9F AJ($2HJ( H<7J(;H<<J(>JJ(J"J(!J""J('J(c                   ddl m}m}m}m}m}m}m}	m}
m	} ddl
m}m}m}m} ddlm}  |d          }|r|                    d          sQt%          d           t%                       	 t'          j        t+          |dd	          t+          |d
d	          t+          |dd	          t+          |dd	          t-          t+          |dd                    t+          |dd	          pdt+          |dd	          t-          t+          |dd                              } |
||d                    	  |            pi } ||           n# t.          $ r Y nw xY wnE# t0          $ r t%          d           Y d	S t.          $ r}t%          d|            Y d	}~d	S d	}~ww xY wd	S ddlm}m}m}m}m}m}  |            }|st%          d           d	S 	  |            }n# t.          $ r}tA          ||          o|j!        }tA          ||          r |	|          ntE          |          }|rt%          d|            t%          d           	 t'          j        d	d	d	d	ddd	d          } |
||d                    n)# t.          $ r}t%          d|            Y d	}~nd	}~ww xY wY d	}~d	S t%          d|            Y d	}~d	S d	}~ww xY w |d          }  |d          }!|!s"	  |d          }"|"r|"}n# t.          $ r Y nw xY wd}#	  |d          }$|$r|$                    d d          }#n# t.          $ r Y nw xY wg }%d}&|!rY	 dd!l#m$}'m%}(  |(d          }) |'|)d"#          pd}&n# t.          $ r d}&Y nw xY w ||| |#          \  }}  ||| d$          \  }}%n ||| |#          \  }} |s|%st%          d%           d	S |!rG|sEt%          d&           |%r2dd'l m&}* |#p|*'                    d(          }+t%          |&pd)|+ d*           d	S t%          d+tQ          |           d,            |||| |%|#|&d|                    d-d          |                    d.d          /	  	        },|,rd ||,           |                    d-d          }- |d|-            |            } |                     d0          }.tA          |.tR                    rtS          |.          }/nBtA          |.tD                    r+|.*                                rd1|.*                                i}/ni }/d|/d2<   |,|/d1<   |-r-|-*                                r|-'                    d(          |/d-<   n|/+                    d-d	           tY          |/           |/| d0<    |d3          r |d3d            |d4d            ||            t%          d5|, d6            ||            d	S t%          d7           d	S )8z8Nous Portal provider: ensure logged in, then pick model.r   )	get_provider_auth_staterM   rN   _update_config_for_provider resolve_nous_runtime_credentials	AuthErrorformat_auth_error_login_nousPROVIDER_REGISTRY)rP   rd   re   save_env_value)prompt_enable_tool_gatewaynousaccess_tokenz.Not logged into Nous Portal. Starting login...
portal_urlNinference_url	client_idscope
no_browserFtimeout      .@	ca_bundleinsecure)r   r   r   r   r   r   r   r   Login cancelled or failed.Login failed: )get_curated_nous_model_idsr[   check_nous_free_tierpartition_nous_models_by_tier&union_with_portal_free_recommendations&union_with_portal_paid_recommendationsz,No curated models available for Nous Portal.zSession expired: z&Re-authenticating with Nous Portal...
zRe-login failed: zCould not verify credentials: T)force_freshr\   r   portal_base_url)&format_nous_portal_entitlement_messageget_nous_portal_account_infozpaid Nous models)
capability)	free_tierz4No models available for Nous Portal after filtering.z#No free models currently available.)DEFAULT_NOUS_PORTAL_URL/zUpgrade at z to access paid models.zShowing =    curated models — use "Enter custom model name" for others.r   rS   )r^   r_   unavailable_modelsr   unavailable_messager`   ra   rb   rf   rg   rh   OPENAI_BASE_URLOPENAI_API_KEYrm   z (via Nous Portal)rn   )-r   r   rM   rN   r   r   r   r   r   r   rq   rP   rd   re   r   hermes_cli.nous_subscriptionr   r   r;   argparse	Namespacegetattrboolr   
SystemExitrr   r   r[   r   r   r   r   r   relogin_requiredr	   hermes_cli.nous_accountr   r   r   rstripr   r   r>   r   r   )0rs   r^   argsr   rM   rN   r   r   r   r   r   r   rP   rd   re   r   r   state	mock_args
_refreshedexcr   r[   r   r   r   r   rZ   credsreloginmsg	login_excr_   r   refreshed_creds_nous_portal_url_nous_stater   r   r   r   _account_infor   _urlry   r   current_model_cfg	model_cfgs0                                                   r'   _model_flow_nousr     s=	   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
            HGGGGG##F++E 		.11 >???	 *"4t<<%dOTBB!$T::dGT22lE B BCCi66>$!$T::gdJ>>??	 	 	I K	#4V#<===([]]0b
**:6666    	 	 	.///FF 	 	 	(3(()))FFFFF	 	
                +*,,I <===0022   S),,E1E(23	(B(BP$$$C 	+c++,,,;<<<7$.#"&"$ ""	 	 		 I'8'@AAAA 7 7 75)55666666667FFFFF4s44555-2 '&v..G %$666I 
		>>"  O  (' 	 	 	 D	 --f55 	F*/@"EE    %' 
	%       
 98TJJJM66!1        	% 	% 	%"$	%CCw 0
 
	7 )F(Ew$)
 )
 )
%	%% DCw 0
 
	7  / DEEE  3444 	V??????$?(?GGLLD%T)Tt)T)T)TUUU	`3y>>```   '&#-#/:r22		)R00
 
 
H   8$$$		*b11##FM::: "JJw//'.. 	.//II)3// 	4E4K4K4M4M 	"$5$;$;$=$=>III &	*'	) 	,]0022 	,$1$8$8$=$=Ij!!MM*d+++(333#w=*++ 	1N,b111N+R000FCxCCCDDD""6*****ls   *CE -E E 
EE EE F2	F;FF
G 
K  A$J;.I43J;4
J>JJ;JJ;#J;;K K. .
K;:K;#L% %
L21L2<#M   M/.M/c                ,   ddl m}m}m}m}m}m}m} ddlm	}	  |            }
|

                    d          rt          d           t                       t          d          }|dk    rt          d           t                       	 t          j                    } |||d	         d
           nE# t          $ r t          d           Y dS t           $ r}t          d|            Y d}~dS d}~ww xY w |            }
|

                    d          st          d           dS n|dk    rdS nt          d           t                       	 t          j                    } |||d	                    nE# t          $ r t          d           Y dS t           $ r}t          d|            Y d}~dS d}~ww xY wd}	  |            }|
                    d          r|
                    d          }n# t           $ r Y nw xY w|s7	 ddl m}  |            }|
                    d          }n# t           $ r Y nw xY w |	|          } |||d	||pd          }|r, ||            |d	|           t          d| d           dS t          d           dS )z9OpenAI Codex provider: ensure logged in, then pick model.r   )get_codex_auth_statusrM   rN   r   _login_openai_codexr   DEFAULT_CODEX_BASE_URL)get_codex_model_ids	logged_inu     OpenAI Codex credentials: ✓zOpenAI Codex credentials:r/   z&Starting a fresh OpenAI Codex login...zopenai-codexTforce_new_loginr   Nr   zLogin failed.r0   z/Not logged into OpenAI Codex. Starting login...rS   )!resolve_codex_runtime_credentials)r   r   r^   r`   ra   rb   rm   z (via OpenAI Codex)rn   )r   r   rM   rN   r   r   r   r   hermes_cli.codex_modelsr   r   r;   rG   r   r   r   r   r   )rs   r^   r   rM   rN   r   r   r   r   r   statusrF   r   r   _codex_token_codex_statusr   _codex_credscodex_modelsry   s                       r'   _model_flow_openai_codexr     s                     <;;;;;""$$Fzz+ &/00001LMMX:;;;GGG$.00	##%n5$(    
    2333   ,s,,--- +*,,F::k** o&&& xF   	?@@@	 *,,I	+<^+LMMMM 	 	 	.///FF 	 	 	(3(()))FFFFF	 L--//[)) 	8(,,Y77L    	IIIIII<<>>L'++I66LL 	 	 	D	 '&LAAAL&&#'/$*  H  8$$$##N4JKKKDxDDDEEEEEls`   'B0 0C2	C2C--C2%E3 3F5	F5F00F5;4G0 0
G=<G=%H) )
H65H6)r   c          	        ddl m}m}m}m}m}m}m}	m}
 ddl	m
}  |            }|                    d          rt          d           t                       t          d          }|dk    rt          d           t                       	 t          j        t!          t#          |d	d
                    t#          |dd                    } |||
d         d           n# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY w|dk    rdS nt          d           t                       	 t          j        t!          t#          |d	d
                    t#          |dd                    } |||
d                    nE# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY w|	}	  |            }|                    d          pd                                                    d          p|}n# t&          $ r Y nw xY wt-          |                    d          p|                    d          pg           } |||p|r|d         nd          }|r, ||            |d|           t          d| d           dS t          d           dS )zRxAI Grok OAuth (SuperGrok / Premium+) provider: ensure logged in, then pick model.r   )get_xai_oauth_auth_statusrM   rN   r   %resolve_xai_oauth_runtime_credentials_login_xai_oauthDEFAULT_XAI_OAUTH_BASE_URLr   _PROVIDER_MODELSr   u8     xAI Grok OAuth (SuperGrok / Premium+) credentials: ✓z2xAI Grok OAuth (SuperGrok / Premium+) credentials:r/   z#Starting a fresh xAI OAuth login...r   Fr   N)r   r   z	xai-oauthTr   r   r   r0   zHNot logged into xAI Grok OAuth (SuperGrok / Premium+). Starting login...r   r   r   xaizgrok-build-0.1)r^   rm   u.    (via xAI Grok OAuth — SuperGrok / Premium+)rn   )r   r   rM   rN   r   r   r   r   r   rr   r   r   r;   rG   r   r   r   r   r   r   r>   r   r   )_configr^   r   r   rM   rN   r   r   r   r   r   r   r   rF   r   r   r   r   modelsry   s                       r'   _model_flow_xai_oauthr  U  s   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 322222&&((Fzz+ *HIII0@
 
 X7888GGG$.#GD,$F$FGG#D)T::  	 ! %k2$(    
    2333   ,s,,--- xF   	XYYY	 *lE B BCCi66  I Y(9+(FGGGG 	 	 	.///FF 	 	 	(3(()))FFFFF	 *H5577IIj))/R6688??DDP    "&&{33X7G7K7KE7R7RXVXYYF&&v]=y\bOxvVWyyhxzzzH 8$$$##K:::_x___`````lsQ   
AC! !D#=	D#DD#AF! !G#=	G#GG#)AH2 2
H?>H?c                   ddl m} ddlm}m}m}m}m}m} ddl	m
}	  |            }
|
                    d          st          d           t          d           |
                    d          }|rt          d	|            |
                    d
          r%t          d|
                    d
                      dS d}	  |d          } |	|d         |d                   }n# t          $ r Y nw xY w|st          |          }|p|r|d         nd} |||d|          }|r, ||            |d|           t          d| d           dS t          d           dS )zAQwen OAuth provider: reuse local Qwen CLI login, then pick model.r   )_DEFAULT_QWEN_PORTAL_MODELS)get_qwen_auth_status resolve_qwen_runtime_credentialsrM   rN   r   DEFAULT_QWEN_BASE_URLfetch_api_modelsr   zNot logged into Qwen CLI OAuth.zRun: qwen auth qwen-oauth	auth_filezExpected credentials file: errorzError: NT)refresh_if_expiringrS   r   zqwen3-coder-plusz
qwen-oauthr^   r`   ra   rm   z (via Qwen OAuth)rn   )ro   r  r   r  r  rM   rN   r   r  rr   r
  r   r;   r   r   )r  r^   r  r  r  rM   rN   r   r  r
  r   r  r  r   rg   ry   s                   r'   _model_flow_qwen_oauthr    s5   ;;;;;;                322222!!##F::k"" /000)***JJ{++	 	=;	;;<<<::g 	31FJJw//11222 F00TJJJ!!%	"2E*4EFF    3122LV Kq		9KG&&%.	  H  8$$$##L2GHHHBxBBBCCCCCls   $C' '
C43C4c           
     B   ddl m}m}m}m}m}m}m}	m}
m	}  |d          }|r|
                    d          st          d           t                       	 t          j        t          |dd          pdt          t          |d	d
                    t          |dd          pd          } |
||d                    nE# t           $ r t          d           Y dS t"          $ r}t          d|            Y d}~dS d}~ww xY w	  |            }n+# |$ r#}t           |	|                     Y d}~dS d}~ww xY wddlm} |
                    dg           } |||d|d                   }|sdS  ||            |d|d                    t          d|            dS )z:MiniMax OAuth provider: ensure logged in, then pick model.r   )	r   rM   rN   r   )resolve_minimax_oauth_runtime_credentialsr   r   _login_minimax_oauthr   zminimax-oauthr   z0Not logged into MiniMax. Starting OAuth login...regionNglobalr   Fr   r   )r  r   r   r   r   r   r   )r`   ra   u   ✓ Using MiniMax model: )r   r   rM   rN   r   r  r   r   r  r   r   r;   r   r   r   r   r   r   rr   r   )rs   r^   r   r   rM   rN   r   r  r   r   r  r   r   r   r   r   r   rZ   ry   s                      r'   _model_flow_minimax_oauthr    s   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 $#O44E 		.11 @AAA	 *tXt44@lE B BCCi66>$  I
 ! ,=o,NOOOO 	 	 	.///FF 	 	 	(3(()))FFFFF	99;;   $$%%% 322222 $$_b99I&&(z*	  H  x   z1BCCC	
3
3
344444s7   A'B? ?D	D$C<<D
D D8D33D8c           
       % ddl m}m}m} ddlm}m} ddlm}m	}m
} ddlm}	  |d          pd}
 |d          pd}t          d	           |
rt          d
|
            |rt          d|dd          d           t                       	 t          d|
pd d                                          } |	d|r|dd         dz   nd d                                          }n'# t           t"          f$ r t          d           Y dS w xY w|s|
st          d           dS |p|
}|                    d          st          d| d           dS |p|}|                    d                                          %t+          %fddD                       }|r%                    d          st                       t          d           t          d           t          d|                    d           d           	 t          d                                                                           }n# t           t"          f$ r d!}Y nw xY w|d"v r.|                    d          dz   }|r|}t          d#|            t                       dd$lm}  |||          }|                    d%          r;|                    d&          r&t          d'|d&          d(           |d&         }|r|}n|                    d)          Lt          d*|                    d+           d,t5          |                    d)          pg            d-           n}t          d.|                    d+           d/           |                    d0          rB|d0         }|                    d          rt          d1|            nt          d2|            |                     d3          }d}t7          |t8                    r6t;          |                    d4          pd                                          } |||5          }|rt          d6|            nt          d7           d}|                    d)          pg }	 t5          |          d8k    r{t          d9|d                     t          d:                                                                          }|d"v r
|d         }nt          d;                                          }nt5          |          d8k    rt          d<           t=          |d8          D ]\  }}t          d=| d>|            t          d?t5          |           d@                                          }|                                rCd8tA          |          cxk    rt5          |          k    rn n|tA          |          d8z
           }n&|r|}n!t          d;                                          }t          dA                                          } ||          }t          dB| d                                          p|} n'# t           t"          f$ r t          d           Y dS w xY wd}!|rz	 tA          |!                    dCd          !                    dDdE          !                    dFdE                    }!|!dk    rd}!n%# tD          $ r t          dG| dH           d}!Y nw xY w|r ||            |            }"|"                    d3          }#t7          |#t8                    s|#rdI|#ini }#|#|"d3<   dJ|#dK<   ||#dL<   |r||#dM<   |r||#d4<   n|##                    d4d            ||"            |             t9          |#          | d3<   t          dN| dO| dP           n|s|r
 |             |                     d3          }$t7          |$t8                    s|$rdI|$ini }$dJ|$dK<   ||$dL<   |r||$dM<   |r||$d4<   n|$#                    d4d           |$| d3<   t          dQ            ||||pd|!| |R           tI          || S           dS )TzCustom endpoint: collect URL, API key, and model name.

    Automatically saves the endpoint to ``custom_providers`` in config.yaml
    so it appears in the provider menu on subsequent runs.
    r   )_auto_provider_name!_prompt_custom_api_mode_selection_save_custom_providerr   )rP   rd   re   masked_secret_promptr   r   r   z0Custom OpenAI-compatible endpoint configuration:z  Current URL: z  Current key: N   ...zAPI base URL [ze.g. https://api.example.com/v1r   	API key [optional
Cancelled.zNo URL provided. Cancelled.zhttp://https://Invalid URL: & (must start with http:// or https://)r   c              3      K   | ]}|v V  	d S N ).0h
_url_lowers     r'   	<genexpr>z%_model_flow_custom.<locals>.<genexpr><  s;         	
Z     r|   )	localhostz	127.0.0.1z0.0.0.0z:11434z:8080z:5000z/v1z+  Hint: Did you mean to add /v1 at the end?z@  Most local model servers (Ollama, vLLM, llama.cpp) require it.z  e.g. z  Add /v1? [Y/n]: r   >   r   yyesz  Updated URL: )probe_api_modelsused_fallbackresolved_base_urlz)Warning: endpoint verification worked at zL/models, not the exact URL you entered. Saving the working base URL instead.r  zVerified endpoint via 
probed_url (z model(s) visible)z,Warning: could not verify this endpoint via z. Hermes will still save it.suggested_base_urlz8  If this server expects /v1 in the path, try base URL: z-  If /v1 should not be in the base URL, try: rf   rj   )current_api_modez  API mode: z  API mode: auto-detectr1   z  Detected model: z  Use this model? [Y/n]: z&Model name (e.g. gpt-4, llama-3-70b): z  Available models:r   r5   z  Select model [1-z] or type name: z8Context length in tokens [leave blank for auto-detect]: zDisplay name [,k000KzInvalid context length: u    — will auto-detect.rg   customrh   r   rS   rm    (via )zFEndpoint saved. Use `/model` in chat or `hermes model` to set a model.)context_lengthrU   rj   r   )%ro   r  r  r  r   rN   rO   rq   rP   rd   re   hermes_cli.secret_promptr  r;   r=   r>   r?   r@   r   r   loweranyendswithrr   r/  r   r   r   r   r	   r<   isdigitr   replacer   r   r(   )&rs   r  r  r  rN   rO   rP   rd   re   r  current_urlcurrent_keyr   rS   effective_urleffective_key_looks_local_add_v1r/  probe	suggestedr   r5  rj   
model_namedetected_modelsconfirmrC   mpickcontext_length_strr   display_namer=  rz   rf   _caller_modelr*  s&                                        @r'   _model_flow_customrT    s    nmmmmmmmmmGGGGGGGGIIIIIIIIII======- 1228bK- 0117RK	
<=== /---... 64BQB444555	GGG	R[M,MRRR
 

%'' 	 '&S;NBQB%//JSSS
 

%'' 	 x(   n  K +,,, +M##$;<< SmSSSTTT*{M
 %%c**0022J    R    L  J//66 ;<<<PQQQ6,,S11666777	0117799??AAGG!8, 	 	 	GGG	&&&)0055=M )(3M33444222222]M::Eyy!! Seii0C&D&D SS>Q8R S S S	
 	
 	
 12 	%$H	8			(CUYY|%<%< C CEIIh''-2..C C C	
 	
 	
 	

 	*599\;R;R * * *	
 	
 	
 99)** 	S23I!!%(( SZyZZ    QiQQRRR 

7++#T** P044Z@@FBGGMMOO00)  H  )'X''(((('((( Jii))/RO1$$;q'9;;<<<788>>@@FFHHG***,Q/

"#KLLRRTT

!!A%%'(((!/155 ' '1oQoo!oo&&&&KS%9%9KKK egg  ||~~ "!s4yy"H"H"H"HC4H4H"H"H"H"H"H,SYY];

 "!
GHHNNPPJ"F
 

%'' 	
 +*=99?l???@@FFHHXLx(   n N "
	" "**333e$$e$$ N
 ""!% 	" 	" 	"W-?WWWXXX!NNN	"  ,X:&&& kmm  %&& 	!*/7Y&&RE CL$j)j 	-,E) 	( (E*IIj$'''C u++wIzIIIIIJJJJ 	"w 	"!!! 

7++-.. 	P:GOY66RM$,j!$1j! 	5'4M)$ 	0(0M*%%j$///'wVWWW b%    4"     sK   AC% % D	D	?3H3 3I	I	9GY  Y;:Y;A[ [98[9c                b   ddl m}m} ddlm}m}m}m} ddlm	} | 
                    di           }	t          |	t                    r|	
                    d          dk    rt          |	
                    dd	          pd	          }
t          |	
                    d
d	          pd	          }t          |	
                    d          pd                                                                          pd}|	
                    d          pi }t          |t                    r|ni }nd	}
d	}d}i } |d          pd	}t!                       t!          d           t!          d           t!                       t!          d           t!          d           t!          d           t!          d           t!                       |
rt!          d|
            |r|dk    rdnd}t!          d|            |dk    rt!          d           n|rt!          d|dd          d           t!                       	 |
pd }t#          d!| d"                                          }n'# t$          t&          f$ r t!          d#           Y dS w xY w|p|
                    d$          }|st!          d%           dS |                    d&          st!          d'| d(           dS t!                       t!          d)           t!          d*           t!          d+           t!          d,           t!          d-           	 |dk    rd.nd/}t#          d0| d1                                          p|}n'# t$          t&          f$ r t!          d#           Y dS w xY w|d.k    }|rdnd}d	}i }d}d	}|rZ	 dd2lm}m}m}m}m}  nJ# t8          $ r=}!t!                       t!          d3|!            t!          d4           d5}d}Y d}!~!nd}!~!ww xY w|r	t!                        |             st!          d6           t!          d7           t          |
                    d8          pd	                                          }"|"p|}i }|"r|"|d8<   t!                       t!          d9            ||:          }# ||#d;<          }$|$
                    d=          rG|$
                    d>          pg }%|%rd?                    |%          nd@}&t!          dA|& dB| dC           n|$
                    dD          pdE}'|$
                    dF          pdG}(t!          dH|'            t!          dI|(            	 t#          dJ                                                                          })n'# t$          t&          f$ r t!          d#           Y dS w xY w|)r|)dKvrt!          dL           dS 	  ||#M          }n# t<          $ r}!t!          dN|!            d}Y d}!~!nd}!~!ww xY wt!                       ddOlm }* 	  |*dP|r|dd         dQz   ndR d"                                          }+n'# t$          t&          f$ r t!          d#           Y dS w xY w|+p|}|st!          dS           dS t!                       t!          dT           |!                    |||U          },tE          |,j#                  }-|,j$        pd	}.|.r^|.dk    rdnd}/t!          dV|/            |,j%        rt!          dW|,j%         dC           |-r t!          dXtM          |-           dY           nt!          dZ|,j%                    t!                       t!          d[           t!          d\           t!          d]           t!          d^           t!          d_           	 |d`k    rd.nd/}0t#          da|0 d1                                          p|0}1n'# t$          t&          f$ r t!          d#           Y dS w xY w|1d.k    rd`nd}.t!                       d	}2|-rSt!          db           tO          |-ddc         dde          D ]\  }3}4t!          df|3dgdh|4            tM          |-          dck    r#t!          ditM          |-          dcz
   dj           t!                       	 t#          dk|p|-d          d"                                          }5n'# t$          t&          f$ r t!          d#           Y dS w xY w|5s|p|-d         }2n|5(                                rQddtS          |5          cxk    r!tU          tM          |-          dc          k    rn n|-tS          |5          ddz
           }2nW|5}2nT	 t#          dl|pdm d"                                          }6n'# t$          t&          f$ r t!          d#           Y dS w xY w|6p|}2|2st!          dn           dS |+                    |2|||U          }7|s |d|            |            }8|8
                    d          }9t          |9t                    s|9rdo|9ini }9|9|8d<   d|9d<   ||9d<   |.|9d
<   |2|9do<   ||9d<   tY          |9d5p           |r3i }:d:D ]};|
                    |;          }<|<r|<|:|;<   |:r|:|9d<   nd|9v r|9d= nd|9v r|9d= |7r|7|9dq<    ||8            |             t          |9          | d<    |dr          r |drd	            |ds          r |dsd	           |.dk    rdnd}/|rdtndu}=t!                       t!          dv           t!          dw|            t!          dx|/            t!          dy|=            t!          dz|2            |7rt!          d{|7d|d}           nt!          d~           t!                       dS )uk  Azure Foundry provider: configure endpoint, auth mode, API mode, and model.

    Azure Foundry supports both OpenAI-style (``/v1/chat/completions``) and
    Anthropic-style (``/v1/messages``) endpoints, and two authentication
    modes:

    * **API key** (default) — uses ``AZURE_FOUNDRY_API_KEY`` from .env.
    * **Microsoft Entra ID** — keyless, RBAC-based auth via the
      ``azure-identity`` SDK (Managed Identity / Workload Identity / az
      login / VS Code / azd / service principal env vars). Works on both
      OpenAI-style and Anthropic-style endpoints — Microsoft RBAC is
      per-resource and the same ``Azure AI User`` role grants
      both. For OpenAI-style the OpenAI SDK's native callable
      ``api_key=`` contract is used; for Anthropic-style an
      ``httpx.Client`` with a request event hook (built by
      :func:`agent.azure_identity_adapter.build_bearer_http_client`)
      mints a fresh JWT per request because the Anthropic SDK does not
      accept a callable ``auth_token`` natively.

    The wizard auto-detects the transport and available models when
    possible:

    * URLs ending in ``/anthropic`` → Anthropic Messages API.
    * Successful ``GET <base>/models`` probe → OpenAI-style + populates
      a picker with the returned deployment / model IDs.
    * Anthropic Messages probe fallback when ``/models`` fails.
    * Manual entry when every probe fails (private endpoints, etc.).

    Context lengths for the chosen model are resolved via the standard
    :func:`agent.model_metadata.get_model_context_length` chain
    (models.dev, provider metadata, hardcoded family fallbacks).
    r   r   rP   r   rd   re   )azure_detectrf   rh   zazure-foundryr   r   rj   	auth_moderS   entraAZURE_FOUNDRY_API_KEYzAzure Foundry Configurationz2==================================================z9Azure Foundry can host models with either OpenAI-style orz6Anthropic-style API endpoints.  Hermes will probe yourz6endpoint to auto-detect the transport and the deployedzmodels when possible.z  Current endpoint:  ri   zOpenAI-stylezAnthropic-stylez  Current API mode:  entra_idz1  Current auth mode: Microsoft Entra ID (keyless)z  Current auth mode: API key (Nr  z...)zhe.g. https://<resource>.openai.azure.com/openai/v1 or https://<resource>.services.ai.azure.com/anthropiczAPI endpoint URL [r   r   r   z$No endpoint URL provided. Cancelled.r!  r#  r$  zAuthentication:z=  1. API key                  (AZURE_FOUNDRY_API_KEY in .env)zO  2. Microsoft Entra ID       (managed identity / workload identity / az login)zY     Recommended by Microsoft. Works for both OpenAI-style and Anthropic-style endpoints.z?     Requires the 'Azure AI User' role on the Foundry resource.r8   r7   zAuthentication mode [1/2] (z): )EntraIdentityConfigSCOPE_AI_AZURE_DEFAULTbuild_token_providerdescribe_active_credentialhas_azure_identity_installedu-   ⚠ Could not import azure-identity adapter: z  Falling back to API key auth.Fu6   ◐ The 'azure-identity' package is not installed yet.z  Hermes will install it now (the preflight below triggers the lazy-install). To skip lazy installs, run:  pip install azure-identityr   u>   ◐ Probing Microsoft Entra ID credential chain (up to 10s)...)r   g      $@)rs   timeout_secondsokenv_sourcesr   zdefault chainu   ✓ Entra ID token acquired (z, scope=r<  r  zcredential chain exhaustedhintzqRun `az login`, attach a managed identity to this VM, or set AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET.u   ⚠ z  Hint: z4Save Entra config anyway and validate later? [Y/n]: )r-  r.  
Cancelled.)rs   u0   ⚠ Could not build token provider for probing: r  r  r  requiredzNo API key provided. Cancelled.u;   ◐ Probing endpoint to auto-detect transport and models...)rS   token_provideru   ✓ Detected API transport: z    (u
   ✓ Found z# deployed model(s) on this endpointu   ⚠ Auto-detection incomplete: z7Select the API format your Azure Foundry endpoint uses:z.  1. OpenAI-style  (POST /v1/chat/completions)z:     For: GPT models, Llama, Mistral, and most open modelsz)  2. Anthropic-style  (POST /v1/messages)z9     For: Claude models deployed via Anthropic API formatanthropic_messageszAPI format [1/2] (z"Available models on this endpoint:   r1   r   r4   z>2r5   z
  ... and z' more (type name manually if not shown)z+Pick by number, or type a deployment name [zModel / deployment name [ze.g. gpt-5.4, claude-sonnet-4-6z"No model name provided. Cancelled.rg   rk   r=  r   r   zMicrosoft Entra ID (keyless)zAPI keyu   ✓ Azure Foundry configured:z    Endpoint:       z    API mode:       z    Auth:           z    Model:          z    Context length: r6  z tokenszA    Context length: not auto-detected (will fall back at runtime))-r   rN   rO   rq   rP   r   rd   re   
hermes_clirW  r   r   r   r	   r>   r?  r;   r=   r?   r@   r   r   agent.azure_identity_adapterr\  r]  r^  r_  r`  ImportErrorjoinr   r>  r  detectr   r  rj   reasonr   r<   rB  r   r   lookup_context_lengthr   )>rs   r^   rN   rO   rP   r   rd   re   rW  r   current_base_urlr5  current_auth_mode
_cur_entracurrent_entracurrent_api_key_lbl_placeholderr   rF  _auth_defaultauth_choice	use_entraauth_mode_labelrG  entra_overridesrg  entra_scoper\  r]  r^  r_  r`  r   _persisted_scope_overrider  inforc  tagerrrd  ansr  rS   	detectiondiscovered_modelsrj   
mode_labeldefault_choicemode_choiceeffective_modelrC   midrP  rL  ctx_lenrz   rf   clean_entrakeyval
auth_labels>                                                                 r'   _model_flow_azure_foundryr    s   B HGGGGGGG            (''''' 

7B''I)T"" 
y}}Z'@'@O'S'Sy}}Z<<BCCy}}Z<<BCC	k : : GiHHNNPPVVXXe\e]]7++1r
&0T&B&BJ

%#m$;<<BO	GGG	
'(((	(OOO	GGG	
EFFF	
BCCC	
BCCC	
!"""	GGG :8&688999 .  #555 N" 	
 	,d,,---J&&ABBBB	 JHrr/BHHHIII	GGG FF 	
 2222
 

%'' 	 x(   n 1!199#>>M 4555##$;<< SmSSSTTT 
GGG	
	
IJJJ	
[\\\	
efff	
KLLL0J>>CBBBBCCIIKK  	 x(   n s"I$-<jj9O MONK (	(                	( 	( 	(GGGG#GGHHH3444I'OOOOOO	(  F++-- 	JKKK3   %((9(9'(B(B(Hb$I$I$O$O$Q$Q!/I3I$ 	A'@OG$NOOO%%
 
 
 *)$OOO88D>> 	((=117RK,7L$))K(((_CM#MM{MMMNNNN((7##C'CC88F## K  ,,,#T##$$$RSSYY[[aacc%x0   n%%%  s,..l###
	"11AAANN 	" 	" 	"JSJJKKK!NNNNNN	" 	AAAAAA	**_?ZOBQB/%77PZ___ egg G "8, 	 	 	.!!!FF	  2? 	3444F 
GGG	
GHHH##% $  I $(	(8#9#9&,"H V&*<<<NNBS 	 	9Z99::: 	/-)*---... 	XS!233XXX   	B	0@BBCCCGHHH>???JKKK9:::IJJJ	$48L$L$LSSRUN>>>>>??EEGG "! K "8, 	 	 	.!!!FF	 ,7#+=+=''CU 
GGGO 62333 1#2# 6a@@@ 	& 	&FAs$q$$$s$$%%%% !!B&&aS!233b8aaa   		hm>cO`abOchhh egg D "8, 	 	 	.!!!FF	  	#+C/@/COO\\^^ 	#SYY Q Q Q Q#c:K6L6Lb2Q2Q Q Q Q Q Q/D		A>OO"OO	cM,^=^ccc egg J "8, 	 	 	.!!!FF	 %5 2333 00%	 1  G  ?.>>>
+--CGGGEeT"" &+3E""G'E*%E* E*&E)(E+$U5AAAA   	' 	'C!%%c**C '#&C  	(E'NNgeg *")K5kkF7O }&'' .("---}%&& -',,,#+/A#A#AGXJ*3B&&  
GGG	
)***	
0
0
0111	
-
-
-...	
-
-
-...	
2
2
2333 S7W77778888QRRR	GGGGGs   1)I  I?>I?01M" " NN N/ /
O693O11O63V  V21V2W 
X$W==X0Y  Y/.Y/,1_  ``+-c  c=<c=6'f  ggc           	     \  ' ddl m}m}m} ddlm}m} ddlm}m	} ddl
m}	 |d         }
|d         }|                    dd	          }|                    d
d	          }|                    dd	          }|                    dd	          '|                    d          pd	                                }|s"|r t          j                            |d	          } |||          }|                    dd          }t!          |t"                    r|                                dv}g }|                    di           }t!          |t&                    rd |D             }n!t!          |t(                    rd |D             }t+          d|
            t+          d|            'rt+          d'            t+                       |s$|r"t+          dt-          |                      |}n*t+          d           ddi}|r||d<    |	||fi |}|s|r|}|rd}'r'|v r|                    '          }t+          dt-          |           d           	 ddlm} 'fd|D             dgz   } |d |
 d!||d"d#          }t+                       |dk     s|t-          |          k    rt+          d$           d%S ||         }n# t4          t6          t8          t:          j        f$ r) t?          |d&          D ]&\  }}|'k    rd'nd	}t+          d(| d)| |            't+          d(t-          |          d&z    d*           t+                       	 tA          d+t-          |          d&z    d,                                          }|st+          d$           Y d%S tC          |          d&z
  }|dk     s|t-          |          k    rt+          d$           Y d%S ||         }n.# tD          tF          tH          f$ r t+          d-           Y Y d%S w xY wY nw xY w'r_t+          d.           	 tA          d/' d,                                          p'}n# tF          tH          f$ r t+          d-           Y d%S w xY wt+          d0           	 tA          d1                                          }n'# tF          tH          f$ r t+          d-           Y d%S w xY w|st+          d2           d%S  ||            |            }|                    d          } t!          | t&                    s| rd3| ini } | |d<   |rmd4|                                                                %                    d5d6          z   | d7<   | &                    dd%           | &                    d
d%           nd8| d7<    |||          | d<   |r|| d
<   |                    dd	          }!|!r|!| d<   n| &                    dd%            ||            |             |rs |            }|                    d9          }"t!          |"t&                    r=|"                    |          }#t!          |#t&                    r||#d:<   t#          |                    d;d	          pd	                                          }$t#          |                    d
d	          pd	                                          }%tO          |$p|%          }&|&r>|r<t#          |#                    d
d	          pd	                                          s||#d
<   |r<t#          |#                    dd	          pd	                                          s||#d<   |"|d9<    ||           n |||||<           t+          d=|            t+          d>|
 d?| d@           d%S )Aa  Handle a named custom provider from config.yaml custom_providers list.

    Always probes the endpoint's /models API to let the user pick a model.
    If a model was previously saved, it is pre-selected in the menu.
    Falls back to the saved model if probing fails.
    r   )%_custom_provider_api_key_config_value&_custom_provider_base_url_config_valuer  r   rc   r	  rU   r   rj   r   rS   key_envrf   provider_keydiscover_modelsT>   0nofalser  c                n    g | ]2}t          |                                          #t          |          3S r'  )r	   r>   r(  rO  s     r'   
<listcomp>z,_model_flow_named_custom.<locals>.<listcomp>  s1    JJJ3q66<<>>JSVVJJJr|   c                ~    g | ]:}t          |t                    |                                +t          |          ;S r'  )r   r	   r>   r  s     r'   r  z,_model_flow_named_custom.<locals>.<listcomp>  sM     
 
 
*Q*<*<
AB
FF
 
 
r|   z  Provider: z  URL:      z  Current:  z2Using configured models (discover_models: false): zFetching available models...r   g       @zFound z model(s):
)curses_radiolistc                *    g | ]}|k    r| d n|S )
 (current)r'  )r(  rO  saved_models     r'   r  z,_model_flow_named_custom.<locals>.<listcomp>  s>       @AA$4$41    !  r|   r+   zSelect model from r   )ry   cancel_returns
searchablere  Nr1   r  r4   r5   z. Cancelz
Choice [1-r   r   z%Could not fetch models from endpoint.zModel name [z@Could not fetch models from endpoint. Enter model name manually.Model name: zNo model specified. Cancelled.rg   zcustom:r3   -rh   r:  	providersdefault_modelapi_key_ref)rj   u   
✅ Model set to: z   Provider: r3  r<  )(ro   r  r  r  r   rN   rO   rq   rd   re   rr   r
  r   r>   osenvironr   r	   r?  r   r   r;   r   r   hermes_cli.curses_uir  rl  NotImplementedErrorOSError
subprocessSubprocessErrorr<   r=   r   r   r?   r@   rC  r   r   )(rs   provider_infor  r  r  rN   rO   rd   re   r
  rU   r   rj   rS   r  r  config_api_keydiscoverconfigured_models
cfg_modelsr  fetch_kwargsr   r  
menu_itemsrB   rL  rC   rO  r   r  rz   rf   custom_api_modeproviders_cfgprovider_entryoriginal_api_key_reforiginal_api_keyhad_inline_api_keyr  s(                                          @r'   _model_flow_named_customr  \  s	    E  E  E  E  E  E  E  E  E  EGGGGGGGG::::::::222222 DZ(H  R00H	2..G	2..G##GR00K!%%n55;BBDDL  .w .*.."--::='RRN   !2D99H(C   @>>##+??#%""8R00J*d## 
JJZJJJ	J	%	% 

 
&
 
 
 



   	
#
#
#$$$ ,*[**+++	GGG ') '[3GXCYCY[[\\\",---!3' 	0'/L$!!'8DD|DD  	'+ 	'&F ; 	4;&00 ,,{33K0s6{{000111$	======   EK  
J #",T,,,$!  C GGGQww#V,,l###JJ0':;UV 	 	 	!&!,, - -1)*k)9)9r+1+++6++,,,,0s6{{Q000111GGG=Vq===>>DDFF ,'''FF#hhl77cS[[00,'''FF#C[

 18<   n%%% 
	& 
 5666	>k>>>??EEGGV;JJ!8, 	 	 	.!!!FF	 	PQQQ	~..4466JJ!8, 	 	 	.!!!FF	  	2333F z"""
+--CGGGEeT"" &+3E""G 
.%(:(:(<(<(B(B(D(D(L(LSRU(V(VVj		*d###		)T""""$jBB8
 
j  	.-E)#''
B77O $+j		*d###K   Wkmm,,mT** 	!*..|<<N.$// !2</ (+!%%mR88>B( (%'' % $'}'8'8B'G'G'M2#N#N#T#T#V#V %)*>*RBR%S%S"&?&?   2 29b A A GRHHNNPP?
 1?N9- 83~'9'9)R'H'H'NB#O#O#U#U#W#W 807N9-#0K C    	h
XVVVV	
-
-
-...	
-$
-
-(
-
-
-.....so   A"K :K BPAO:OOP&P
P	P

PP%'Q  Q10Q1!R& & S
	S
c                   ddl m}m}m} ddlm}m}m}m}m	}	 ddl
m}
m}m} ddlm}m}m}m}m}m} d}||         } |	|          }|                    dd          }|                    d	d          }|st-          d
           t-                       t-          d           t-          d           t-          d           t-          d           t-          d           t-                       t-          d           t-          d           t-          d           t-          d           t-                       	 t/          d                                          }n&# t2          t4          f$ r t-                       Y dS w xY w|dk    rz	 ddlm}  |            }|r* |
d|           t-          d           t-                       nt-          d           dS n# t:          $ r}t-          d|            Y d}~dS d}~ww xY w|dk    rddlm} 	  |d                                          }n&# t2          t4          f$ r t-                       Y dS w xY w|st-          d           dS 	 dd lm }  ||          \  }} |st-          d!|             dS n# tB          $ r Y nw xY w |
d|           t-          d"           t-                       nt-          d           dS  |	|          }|                    dd          }|                    d	d          }ni|d#v r2dd$l"m#}!  |!|          }"t-          d%|dd&          d'| |" d(           n%|d)k    rt-          d*           nt-          d+           t-                       |j$        }# ||          }$|$rd, |$D             n |||#          }% |||$|-          p|}&|%r-d. |%D             }'t-          d/tK          |'           d0           n6|                    |g           }'|'rt-          d1           t-          d2           |'r ||'|&||#|3          }(n<	 t/          d4                                          }(n# t2          t4          f$ r d}(Y nw xY w|(r@ ||(|$|-          p|(}( |            }) ||)          }* ||(|$|-          }+d},|+r t-          d5|( d6            ||+|*7          }, ||(            |            }-|-                    d8          }.tM          |.tN                    s|.rd9|.ini }.|.|-d8<   ||.d:<   |#|.d;<    ||(|$|-          |.d<<   tQ          |.d=>           |, ||-|,            ||-            |             t-          d?|( d@|j)         d(           |+r-|,dAk    rt-          dB           dS |,rt-          dC|,            dS dS dS t-          dD           dS )EzAGitHub Copilot flow using env vars, gh CLI, or OAuth device code.r   )_current_reasoning_effort"_prompt_reasoning_effort_selection_set_reasoning_effort)r   rM   rN   rO   $resolve_api_key_provider_credentials)r   rd   re   )r   r
  fetch_github_model_cataloggithub_model_reasoning_effortscopilot_model_api_modenormalize_copilot_model_idcopilotrS   r   r   z.No GitHub token configured for GitHub Copilot.z  Supported token types:uL       → OAuth token (gho_*)          via `copilot login` or device code flowuI       → Fine-grained PAT (github_pat_*)  with Copilot Requests permissionu=       → GitHub App token (ghu_*)     via environment variableuA       ✗ Classic PAT (ghp_*)          NOT supported by Copilot APIz
  Options:z1    1. Login with GitHub (OAuth device code flow)z    2. Enter a token manually    3. Cancelz  Choice [1-3]: Nr7   )copilot_device_code_loginCOPILOT_GITHUB_TOKENz  Copilot token saved.z  Login cancelled or failed.z  Login failed: r8   r  z   Token (COPILOT_GITHUB_TOKEN):   Cancelled.)validate_copilot_tokenu     ✗ z  Token saved.>   GH_TOKENGITHUB_TOKENformat_secret_source_suffixz  GitHub token: r  u	   ... ✓ (r<  zgh auth tokenu*     GitHub token: ✓ (from `gh auth token`)u     GitHub token: ✓c                d    g | ]-}|                     d           |                     d d          .S r   r   r   r(  items     r'   r  z'_model_flow_copilot.<locals>.<listcomp>  s5    BBB488D>>B$		BBBr|   catalogrS   c                    g | ]}||S r'  r'  )r(  model_ids     r'   r  z'_model_flow_copilot.<locals>.<listcomp>  s    GGG8hGhGGGr|     Found  model(s) from GitHub CopilotL     ⚠ Could not auto-detect models from GitHub Copilot — showing defaults.?    Use "Enter custom model name" if you do not see your model.r   r  r4   z supports reasoning controls.)current_effortrf   rg   rh   r   rj   Frk   rm   r;  nonez"Reasoning disabled for this model.zReasoning effort set to: rn   )*ro   r  r  r  r   r   rM   rN   rO   r  rq   r   rd   re   rr   r   r
  r  r  r  r  r   r;   r=   r>   r?   r@   hermes_cli.copilot_authr  r   r>  r  r  rl  hermes_cli.env_loaderr  inference_base_urlr   r   r   r   rU   )/rs   r^   r  r  r  r   rM   rN   rO   r  r   rd   re   r   r
  r  r  r  r  rY   rt   r   rS   r   rF   r  tokenr   r  new_keyr  validr   r  	bw_suffixeffective_baser  live_modelsnormalized_current_model
model_listry   initial_cfgr  reasoning_effortsselected_effortrz   rf   s/                                                  r'   _model_flow_copilotr    s   tttttttttt              KJJJJJJJJJ                K,G00==Eii	2&&GYYx$$F M>???()))Z	
 	
 	
 	YZZZMNNNQRRRlABBB-...o	-..4466FF!8, 	 	 	GGGFF	 S==MMMMMM1133 "N#95AAA2333GGGG8999F     .../// s]]EEEEEE../QRRXXZZ%x0     n%%%JJJJJJ33G<<
s .3..)))F    N17;;;"###GGGG.!!!F44[AA))Ir**8R((111IIIIII33F;;IOWRaR[OO6O9OOOPPPP&&>????'(((/N((11G 	7BBBBBBg~66  	#"	
 	
 	
 	
    	UGG{GGG
GZGGGHHHH%))+r::
 	U^   STTT **2(+#
 
 
	^,,2244HH!8, 	 	 	HHH	  2&&   
  	 "kmm22;??::
 
 

  	>x>>>???@@!.  O 	8$$$kmm  %&& 	!*/7Y&&RE CL'j*j22
 
 
j
 	)uEEEE&!!#777CFxFFw|FFFGGG 	E&((:;;;;;  EC/CCDDDDD		E 	EE E 	lsa   8!E E=<E=AG 
G= G88G=H+ +II%(J 
JJ1!Q Q)(Q)c                   ddl m}m}m}m}m}m}m} ddlm	}	m
}
m} ddlm}m} ~ d}||         } ||          }|                    d          p|                    d          pd}|                    d	          p|j        }t#          d
           t#          d           t#          d           t#          d|            t#          d|            t#                       	  ||          }n9# t$          $ r,}t#          d|            t#          d           Y d}~dS d}~ww xY w|                    d	          p|}d}	  |d          }|                    dd          }n# t$          $ r Y nw xY w |
|          } ||||          p|}|r-d |D             }t#          dt'          |           d           n6|	                    dg           }|rt#          d           t#          d           |r ||||||          }n<	 t)          d                                          }n# t,          t.          f$ r d}Y nw xY w|st#          d           dS  ||||          p|} ||            |            }|                    d          }t1          |t2                    s|rd|ini }||d<   ||d<   ||d	<   d |d!<   t5          |d"#            ||            |             t#          d$| d%|j         d&           dS )'z4GitHub Copilot ACP flow using the local Copilot CLI.r   )r   rM   rN   rO   $get_external_process_provider_statusr  -resolve_external_process_provider_credentials)r   r  r  rc   zcopilot-acpresolved_commandcommandr  r   z?  GitHub Copilot ACP delegates Hermes turns to `copilot --acp`.zB  Hermes currently starts its own ACP subprocess for each request.zH  Hermes uses your selected model as a hint for the Copilot ACP session.z  Command: z  Backend marker: u     ⚠ z[  Set HERMES_COPILOT_ACP_COMMAND or COPILOT_CLI_PATH if Copilot CLI is installed elsewhere.Nr   rS   r  c                d    g | ]-}|                     d           |                     d d          .S r  r  r  s     r'   r  z+_model_flow_copilot_acp.<locals>.<listcomp>$  s5    OOOTOdhhtR((OOOr|   r  r  r  r  r   r  rn   rf   rg   rh   ri   rj   Frk   rm   r;  r<  )r   r   rM   rN   rO   r  r  r  rr   r   r  r  rq   rd   re   r   r  r;   r   r   r=   r>   r?   r@   r   r   r   rU   )rs   r^   r   rM   rN   rO   r  r  r  r   r  r  rd   re   rY   rt   r   r  r  r   r   catalog_api_keycatalog_credsr  r  r  ry   rz   rf   s                                r'   _model_flow_copilot_acpr    s                             
 ;:::::::K,G11+>>F

%&&L&**Y*?*?L9  ZZ
++Iw/IN	
KLLL	
NOOO	
TUUU	
*(
*
*+++	
/~
/
/000	GGG==kJJ   nsnni	
 	
 	
 	 YYz**<nNO<<YGG'++Ir::    )(99G""#	
 	
 	
 	
    	UOOWOOO
GZGGGHHHH%)))R88
 	U^   STTT **2(++
 
 
	^,,2244HH!8, 	 	 	HHH	  l 	#"#	
 	
 	
 	
   x   
+--CGGGEeT"" &+3E""G#E*&E**E*$U5AAAAK	
B8
B
B7<
B
B
BCCCCCs<   #C/ /
D%9!D  D%!E$ $
E10E1!H* *I ?I c                Z   ddl m} ddlm}m}m}m}m} ddlm	}m
}	m}
m} ddlm} d}||         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} ||          pt#          j        |d          }|r n' ||||          \  }}|rd	S |                    d
          }|r|}t)          d|            n|j        }t)          d|            |r ||          r |	|d           t)                       |                    |rdndg           }|r ||||||          }n<	 t/          d                                          }n# t2          t4          f$ r d	}Y nw xY w|r ||            |
            }|                    d          }t7          |t8                    s|rd|ini }||d<   ||d<   ||d<   |                    dd	           t=          |d            ||            |             |rdnd}t)          d| d| d           d	S t)          d           d	S )u  Kimi / Moonshot model selection with automatic endpoint routing.

    - sk-kimi-* keys   → api.kimi.com/coding/v1  (Kimi Coding Plan)
    - Other keys        → api.moonshot.ai/v1      (legacy Moonshot)

    No manual base URL prompt — endpoint is determined by key prefix.
    r   rI   )r   KIMI_CODE_BASE_URLrM   rN   rO   rV  r   zkimi-codingr   rX   Nzsk-kimi-u$     Detected Kimi Coding Plan key → u     Using Moonshot endpoint → moonshotr   zEnter model name: rf   rg   rh   r   rj   Frk   zKimi CodingMoonshotrm   r;  r<  rn   )ro   rJ   r   r   r  rM   rN   rO   rq   rP   r   rd   re   rr   r   rW   base_url_env_varr  getenvr   r;   r  r   r=   r>   r?   r@   r   r   r   r   )rs   r^   rJ   r   r  rM   rN   rO   rP   r   rd   re   r   rY   rt   r  base_url_envru   evrw   is_coding_planr  r  ry   rz   rf   endpoint_labels                              r'   _model_flow_kimir  X  s    0/////                         322222K,G-4-EMg&q))2G+1rL L&  $}R((=BIb",=,= 	E	 */;  L%   ",,Z88N A+E^EEFFFF 3?~??@@@ )l33 )|R(((	GGG "%%~&Umm:WYZZJ **'(+(
 
 
	12288::HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j		*d###(uEEEEC*8HjHxHH~HHHIIIIIls   /!E E'&E'c                4   ddl m}m}m}m} ddlm}m}m}m	}	 ddl
m}
m}m}m} ddlm}m} d}||         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} |
|          pt)          j        |d          }|r n' ||||          \  }}|rd	S d}|r  |
|          pt)          j        |d          }|s`|                     d
          }t/          |t0                    r6t3          |                    d          pd                                          } ||p|j                  }dd |d           dfdd |d           dfg}g }|D ]>\  }}||k    r|                    d|| df           '|                    ||f           ?|                    d            |d |D                       }|||         d         dk    rt=          d           d	S ||         d         } ||          } |r |||             |||           }!|!r+|!}"t=          dt?          |"           d|j          d           n0|                    |g           }"|"rt=          d|j          d           |"r ||"||| |          }#n<	 tC          d                                          }#n# tD          tF          f$ r d	}#Y nw xY w|#r ||#            |            }$|$                    d
          }%t/          |%t0                    s|%rd|%ini }%|%|$d
<   ||%d<   | |%d<   |%$                    dd	           tK          |%d !            ||$            |	             t1          |%          | d
<   t=          d"|# d#|j          d           d	S t=          d           d	S )$z6StepFun Step Plan flow with region-specific endpoints.r   )_infer_stepfun_regionrJ   _prompt_provider_choice_stepfun_base_url_for_regionr   rM   rN   rO   rV  )r   r
  stepfunr   rX   Nrf   r   internationalzInternational (r<  chinazChina (u     ← currently active)r0   r+   c                    g | ]\  }}|S r'  r'  )r(  _rD   s      r'   r  z'_model_flow_stepfun.<locals>.<listcomp>  s    )P)P)PHAu%)P)P)Pr|   r0   rn   r   model(s) from  APIz$  Could not auto-detect models from u,    API — showing Step Plan fallback catalog.r   r  rg   rh   rj   Frk   rm   r;  )&ro   r  rJ   r  r  r   r   rM   rN   rO   rq   rP   r   rd   re   rr   r   r
  rW   r  r  r  r   r   r   r	   r>   r  insertr   r;   r   rU   r=   r?   r@   r   r   )&rs   r^   r  rJ   r  r  r   rM   rN   rO   rP   r   rd   re   r   r
  rY   rt   r  r  ru   r  rw   current_baser   current_regionregion_choicesordered_regions
region_keyrD   
region_idxselected_regionr  r  r  ry   rz   rf   s&                                         r'   _model_flow_stepfunr    ss   }}}}}}}}}}}}                       EDDDDDDDK,G-4-EMg&q))2G+1rLL&  $}R((=BIb",=,= 	E	 */;  L%  L R$}\22Qbib6Q6Q HJJw''	i&& 	Hy}}Z88>B??EEGGL**<+U7;UVVN N::?KKNNN	
 
D88AADDDEN O+ 8 8
E''""1ze3S3S3S&TUUUU""J#67777/000(()P)P)P)P)PQQJ_Z8;xGGl%j1!4O11/BBN 5|^444""<@@K 	 
KZKKKKKLLLL%))+r::
 	6w| 6 6 6  
  **'(+(
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL'j*j		*d###(uEEEECu++wFxFFw|FFFGGGGGls   !J- -KKc                \   ddl m}m}m} ddlm}m}m}m}	 ddl	m
}
 d| d} |d          pd}|r/dd	lm}  |d          }t          d
|dd          d|            nt          d|            t                       ddlm} 	  |d
                                          }n&# t"          t$          f$ r t                       Y dS w xY w|st          d           dS  |	d|           |}t          d           t                       |
                    dg           }t          dt)          |           d           |r |||d||          }n<	 t+          d                                          }n# t"          t$          f$ r d}Y nw xY w|r ||            |            }|                    d          }t-          |t.                    s|rd|ini }||d<   d|d<   ||d<   |                    dd           t3          |d           |                    di           }t-          |t.                    si }||d<   ||d<    |	d |            |	d!|            ||            |             t          d"| d#| d$           t          d|            dS t          d%           dS )&u   Bedrock API Key mode — uses the OpenAI-compatible bedrock-mantle endpoint.

    For developers who don't have an AWS account but received a Bedrock API Key
    from their AWS admin. Works like any OpenAI-compatible endpoint.
    r   rM   rN   rO   )rd   re   rP   r   r   zhttps://bedrock-mantle.z.api.aws/v1AWS_BEARER_TOKEN_BEDROCKr   r  z  Bedrock API Key: N      ... ✓z  Endpoint: r  r       ✓ API key saved.bedrock
  Showing z curated modelsr:  r     Model ID: rf   rg   rh   r   rj   Frk   r  r   r     Default model set to: z (via Bedrock API Key, r<    No change.)r   rM   rN   rO   rq   rd   re   rP   r   rr   r   r  r  r;   r>  r  r>   r?   r@   r   r   r=   r   r   r   r   )rs   r  r^   rM   rN   rO   rd   re   rP   r   r   mantle_base_urlru   r  source_suffixr  rS   r  ry   rz   rf   bedrock_cfgs                         r'   _model_flow_bedrock_api_keyr&  '  s             
            322222CCCCO !=!;<<BL &EEEEEE334NOOML"$5MMmMMNNNN._..///AAAAAA	**+@AAGGIIGG!8, 	 	 	GGGFF	  	.!!!F17;;;$%%%	GGG "%%i44J	
7s:
7
7
7888 **'%,(
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL$j+j		*d###(uEEEE ggi,,+t,, 	K &H$I 	'666(/:::CSSS&SSSTTT._../////ns$   B& &C	C	!E6 6FFc                T
    ddl m}m}m} ddlm}m} ddlm} 	 ddl	m
}m}	m}
m} n=# t          $ r0 t          d           t          d           t                       Y dS w xY w |            s,t          d	           t          d
           t                        |	            }|rt          d| d           nt          d           t                        |
            }	 t!          d| d                                          }n&# t$          t&          f$ r t                       Y dS w xY w|p|}t          d           t                       t          d           t          d           t          d           t          d           t          d           t                       	 t!          d                                          }n&# t$          t&          f$ r t                       Y dS w xY w|dk    rt)          | ||           dS t          d| d            ||          }|rid}d}g }|D ]W}|d          t+           fd|D                       r&t+           fd|D                       rB|                    |           Xt/                      }|D ]^}|d                               d          r?d  d!d         v r                     d d"          d"         n }|                    |           _g }|D ]9}|d                               d          s |v r$|                    |           :g d#fd$}|                    |%           d& |D             }t          d't9          |           d(t9          |           d)           nJ|                    d*g           }|r!t          d+t9          |           d,           nt          d-           dS |r |||d*d.| d/0          }n<	 t!          d1                                          }n# t$          t&          f$ r d}Y nw xY w|r ||            |            }|                    d2          }t=          |t>                    s|rd3|ini }||d2<   d*|d4<   d.| d/|d5<   |                     d6d           tC          |d78           |                    d*i           }t=          |t>                    si }||d9<   ||d*<    ||            |             t          d:| d;| d<           dS t          d=           dS )>u$  AWS Bedrock provider: verify credentials, pick region, discover models.

    Uses the native Converse API via boto3 — not the OpenAI-compatible endpoint.
    Auth is handled by the AWS SDK default credential chain (env vars, profile,
    instance role), so no API key prompt is needed.
    r   r  rc   r   )has_aws_credentialsresolve_aws_auth_env_varresolve_bedrock_regiondiscover_bedrock_modelsu.     ✗ boto3 is not installed. Install it with:z    pip install boto3Nu<     ⚠ No AWS credentials detected via environment variables.zE  Bedrock will use boto3's default credential chain (IMDS, SSO, etc.)z  AWS credentials: u    ✓z<  AWS credentials: boto3 default chain (instance role / SSO)z  AWS Region [r     Choose authentication method:z)    1. IAM credential chain (recommended)zB       Works with EC2 instance roles, SSO, env vars, aws configurez    2. Bedrock API Keyu<          Enter your Bedrock API Key directly — also supportsz5       team scenarios where an admin distributes keysz  Choice [1]: r8   z  Discovering models in r  )z
stability.zcohere.embedztwelvelabs.zus.stability.zus.cohere.embedzus.twelvelabs.zglobal.cohere.embedzglobal.twelvelabs.)	safeguardvoxtralzpalmyra-visionr   c              3  B   K   | ]}                     |          V  d S r&  )r   )r(  pr  s     r'   r+  z&_model_flow_bedrock.<locals>.<genexpr>  s/      @@3>>!$$@@@@@@r|   c              3  D   K   | ]}|                                 v V  d S r&  r?  )r(  sr  s     r'   r+  z&_model_flow_bedrock.<locals>.<genexpr>  s0      AA1		#AAAAAAr|   )zus.global..   r1   )	zus.anthropic.claude-sonnet-4-6zus.anthropic.claude-opus-4-6zus.anthropic.claude-haiku-4-5zus.amazon.nova-prozus.amazon.nova-litezus.amazon.nova-microzdeepseek.v3zus.meta.llama4-maverickzus.meta.llama4-scoutc                    | d         }t                    D ]!\  }}|                    |          rd||fc S "|                    d          rdd|fS dd|fS )Nr   r   r4  r1      )r<   r   )rO  r  rC   rec_RECOMMENDEDs       r'   	_sort_keyz&_model_flow_bedrock.<locals>._sort_key	  s~    D'C#L11 ' '3>>#&& 'q#;&&&'~~i(( #1c{"q#;r|   )r  c                    g | ]
}|d          S )r   r'  r  s     r'   r  z'_model_flow_bedrock.<locals>.<listcomp>	  s    ///!ag///r|   r  z text model(s) (filtered from z total)r  z  Using z, curated models (live discovery unavailable)zJ  No models found. Check IAM permissions for bedrock:ListFoundationModels.zhttps://bedrock-runtime.z.amazonaws.comr  r   rf   rg   rh   r   rj   Frk   r  r!  z (via AWS Bedrock, r<  r"  )"r   rM   rN   rO   rq   rd   re   rr   r   agent.bedrock_adapterr(  r)  r*  r+  rl  r;   r=   r>   r?   r@   r&  r@  r   setr   splitaddsortr   r   r   r   r   r   )!rs   r^   rM   rN   rO   rd   re   r   r(  r)  r*  r+  auth_varr  region_inputr  ry  r  _EXCLUDE_PREFIXES_EXCLUDE_SUBSTRINGSfilteredrO  profile_base_idsbasededupedr;  r  ry   rz   rf   r%  r:  r  s!                                  @@r'   _model_flow_bedrockrJ    s+            
 ;:::::::222222	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
    >???%&&&	    LMMMUVVV''))H N2H2223333LMMM	GGG ,+--NAnAAABBHHJJx(    +^F 

+,,,	GGG	
5666	
NOOO	
"###	
HIII	
ABBB	GGG,--3355x(    c#FFMBBB 

0V
0
0
0111))&11K I	
 I 	 	AD'C@@@@.?@@@@@ AAAA-@AAAAA OOA 55 	+ 	+AD'C~~011 +/2c!""g~~syya((++3 $$T*** 	 	AD'C>>"455 #AQ:Q:QNN1

 

 

	 	 	 	 	 	###//w///
_s:__c+FVFV___	
 	
 	
 	
 &)))R88
 	X3z??XXX    \   F  **'&NNNN	
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL%jMvMMMj		*d###(uEEEEggi,,+t,, 	K &H$ICOOOfOOOPPPPPnsE   ) 6A#"A#$%D
 
D-,D-+!G G0/G07!P P/.P/c                h   ddl m}m}m} ddlm}m}m} ddlm	}  |d          p |d          pd
                                }	|	rt          d|	 d	           n<t          d
           t          d           t          d           t          d           t                        |            }
|
                    d          }t          |t                    si }t          |                    d          pd          
                                }	 t!          d|pd d          
                                }n&# t"          t$          f$ r t                       Y dS w xY w|p|}t          |                    d          pd          
                                pd}	 t!          d| d          
                                }n&# t"          t$          f$ r t                       Y dS w xY w|p|}|                    dg           pddg}|dk    rd| dnd| d| d} |||d|          }|r ||            |            }
|
                    d          }t          |t                    s|rd|ini }||
d<   d|d <   |                    d!d           |                    d"d           t)          |d#$           |
                    d          }t          |t                    si }||d<   ||d<   ||
d<    ||
            |             t          d%| d&| d'           dS t          d(           dS ))u  Google Vertex AI provider: Gemini via the OpenAI-compatible endpoint.

    Auth is OAuth2 — short-lived tokens minted from a service-account JSON or
    Application Default Credentials (ADC). No static API key. The credential
    *path* lives in .env (VERTEX_CREDENTIALS_PATH / GOOGLE_APPLICATION_CREDENTIALS);
    project ID and region are non-secret and saved to config.yaml under vertex:.
    r   r  )rd   re   rP   r   VERTEX_CREDENTIALS_PATHGOOGLE_APPLICATION_CREDENTIALSr   z,  Vertex credentials: service account JSON (u   ) ✓z;  Vertex credentials: Application Default Credentials (ADC)z5    Vertex uses OAuth2, not a static API key. Either:u9         • run 'gcloud auth application-default login', oruQ         • set VERTEX_CREDENTIALS_PATH in ~/.hermes/.env to a service account JSONvertex
project_idz  GCP project ID [zfrom credentialsr   Nr  r  z  Vertex region [zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-previewzGhttps://aiplatform.googleapis.com/v1beta1/projects/<project>/locations/z/endpoints/openapir"  z@-aiplatform.googleapis.com/v1beta1/projects/<project>/locations/r  rf   rg   rh   r   rj   Frk   r!  z (via Google Vertex AI, r<  r"  )r   rM   rN   rO   rq   rd   re   rP   rr   r   r>   r;   r   r   r   r	   r=   r?   r@   r   r   )rs   r^   rM   rN   rO   rd   re   rP   r   sa_pathrz   
vertex_cfgcurrent_projectproject_inputrO  r  rC  r  r  base_url_previewry   rf   vcfgs                          r'   _model_flow_vertexrV  D	  s`            
 JIIIIIIIII222222 	/00 	=9::	egg	 
  cKWKKKLLLLKLLLEFFFIJJJabbb	GGG
+--C""Jj$'' 
 *..66<"==CCEEOK!F4FKKK
 

%'' 	 x(    1/J 11=X>>DDFFR(NDDDDEEKKMMx(    +^F "%%h33 %'8J X	0	0 	0 	0 	00 0 00 0 0	  '&#!)	  H  8$$$kmm  %&& 	!*/7Y&&RE CL$j		*d###		*d###(uEEEEwwx  $%% 	D'\XHCTTT6TTTUUUUUns$   'D: :EE%G G&%G&r  c                   ddl m} ddlm} d |D             }| pd                                                    d          }d}t          |          D ]%\  }\  }}||                    d          k    r|} n&|rt          |          }d |D             }	|	                    d            ||	|d	
          }
|
| S |
t          |          k    r	 t          d|  d                                          }n'# t          t          f$ r t                       | cY S w xY w|s| S |                    d          st          d           | S |                    d          S ||
         d                             d          S )a  Present a picker for Z.AI endpoint selection during setup.

    Offers the four official Z.AI endpoints (Global, China, Coding Plan
    Global, Coding Plan China) plus a custom-proxy option.  The list is
    sourced from ``ZAI_ENDPOINTS`` in ``hermes_cli.auth`` so it stays in
    sync with the probe list.

    Returns the selected base URL.  Falls back to *current_base* on cancel
    or error.
    r   )r  )ZAI_ENDPOINTSc                     g | ]\  }}}}||fS r'  r'  )r(  r  urlrD   s       r'   r  z(_select_zai_endpoint.<locals>.<listcomp>	  s%    BBB 035s|BBBr|   r   r   c                $    g | ]\  }}| d | dS )r3  r<  r'  )r(  rD   rZ  s      r'   r  z(_select_zai_endpoint.<locals>.<listcomp>	  s-    <<<jeS%!!3!!!<<<r|   zCustom proxy URLzSelect Z.AI / GLM endpoint:)rg   r)   NzCustom base URL [r   r!  M     Invalid URL — must start with http:// or https://. Keeping current value.r1   )ro   r  r   rX  r>   r   r<   r   r   r=   r?   r@   r;   r   )r  r  rX  optionsnormalized_currentr   rB   r  rZ  rA   ry   overrides               r'   _select_zai_endpointr`  	  s    877777------ CBMBBBG&,"3355<<SAA K"7++ ' 'XaC00KE 1  	'g,,K<<G<<<GNN%&&&&&+  H
 3w<<	 BBBBCCIIKKHH!8, 	  	  	 GGG	   	 ""#:;; 	 abbbs###8Q&&s+++s   %C7 7!DDc                  - ddl m} ddlm}m}m}m} ddlm}m	}	m
}
m} ddlm}m}m}m- |         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} ||          pt'          j        |d          }|r n' |||          \  }}|rdS d	k    rS|rP	 dd
lm} n# t.          $ r d}Y nw xY w|3t1          d           |r ||          ndpt'          j        |pdd          p|j        } |||          }|dk    rt1                       t1          d           t1          d           t1          d           t1          d           t1                       t1          d           t1          d           t1                       t1          d           t1                       t1          d           dS |dk    rt1          d           nt1          d           t1                       d}|r  ||          pt'          j        |d          }|s	  |
                                d          pi }t7          |                    d          pd                                                                          k    r6t7          |                    d          pd                                          }n# t.          $ r Y nw xY w|p|j        }dk    r(t=          |          }|r||k    r|r |	||           |}n	 t?          d| d                                          }n'# t@          tB          f$ r t1                       d}Y nw xY w|r5|r3|"                    d          st1          d           n |	||           |}d k    rdd!lm#} dd"lm$} |p|r ||          nd}	  |||#          } n5# |$ r-}!t1          d$|!            t1          d%           g } Y d}!~!nd}!~!ww xY w| r t1          d&tK          |            d'           n;d(k    rIdd)lm&}" |p|r ||          nd} |"||d*+          } | r t1          d&tK          |            d,           nd-k    rHdd.lm} |p|r ||          nd}|                    g           }# |||          }$|$r,|$} t1          d&tK          |            d/|j'         d0           n~g }%	 dd1l(m)}&  |&          }%n# t.          $ r Y nw xY w|%rd2 |%D             }'tU          |%          } |#D ]T}(|(                                |'vr<| +                    |(           |',                    |(                                           Ut1          d&tK          |            d3           n|#} | r t1          d4tK          |            d5           n|                    g           }#g }%	 dd1l(m)}&  |&          }%n# t.          $ r Y nw xY w|%r|#rud6 |%D             }'tU          |%          })|#D ]T}(|(                                |'vr<|)+                    |(           |',                    |(                                           U|)} n|%} t1          d&tK          |            d3           n|#r6tK          |#          d7k    r#|#} t1          d4tK          |            d5           n|p|r ||          nd} |||          }$|$rKtK          |$          tK          |#          k    r+|$} t1          d&tK          |            d/|j'         d0           n$|#} | r t1          d4tK          |            d5           d8v rL-fd9| D             }  -|          }tU          tZ          .                    d: | D                                 } | r || |||;          }*n<	 t?          d<                                          }*n# t@          tB          f$ r d}*Y nw xY w|*rӉd8v r -|*          }* ||*            |
            }+|+                    d          },t_          |,tZ                    s|,rd=|,ini },|,|+d<   |,d<   ||,d<   ta          |,d>?           d8v r ||*          |,d@<   n|,1                    d@d            ||+            |             t1          dA|* dB|j'         dC           dS t1          dD           dS )EzCGeneric flow for API-key providers (z.ai, MiniMax, OpenCode, etc.).r   rI   r  rV  )r   r
  opencode_model_api_modenormalize_opencode_model_idr   rX   Ngemini)probe_gemini_tierz  Checking Gemini API tier...freeuW   ❌ This Google API key is on the free tier (<= 250 requests/day for gemini-2.5-flash).z[   Hermes typically makes 3-10 API calls per user turn (tool iterations + auxiliary tasks),zO   so the free tier is exhausted after a handful of messages and cannot sustainz   an agent session.zX   To use Gemini with Hermes, enable billing on your Google Cloud project and regeneratezK   the key in a billing-enabled project: https://aistudio.google.com/apikeyzY   Alternatives with workable free usage: DeepSeek, OpenRouter (free models), Groq, Nous.z*Not saving Gemini as the default provider.paidu     Tier check: paid ✓z3  Tier check: could not verify (proceeding anyway).rf   rh   r   zaiz
Base URL [r   r!  r\  lmstudio)r   )fetch_lmstudio_models)rS   r   z"  LM Studio rejected the request: zC  Set LM_API_KEY (or update it) to match the server's bearer token.r  z model(s) from LM Studiozollama-cloud)fetch_ollama_cloud_modelsT)rS   r   r]   z model(s) from Ollama Cloudnovitar	  r  r  )list_agentic_modelsc                6    h | ]}|                                 S r'  r2  r  s     r'   	<setcomp>z/_model_flow_api_key_provider.<locals>.<setcomp>
       777a		777r|   z" model(s) from models.dev registryr  r   c                6    h | ]}|                                 S r'  r2  r  s     r'   ro  z/_model_flow_api_key_provider.<locals>.<setcomp>
  rp  r|   r  >   opencode-goopencode-zenc                (    g | ]} |          S r'  r'  )r(  r  rc  rY   s     r'   r  z0_model_flow_api_key_provider.<locals>.<listcomp>
  s4     
 
 
>A''S99
 
 
r|   c              3     K   | ]}||V  	d S r&  r'  )r(  r  s     r'   r+  z/_model_flow_api_key_provider.<locals>.<genexpr>
  s'      'I'IS'I'I'I'I'I'I'Ir|   r   r  rg   Frk   rj   rm   r;  r<  rn   )2ro   rJ   r   r   rM   rN   rO   rq   rP   r   rd   re   rr   r   r
  rb  rc  rW   r  r  r  agent.gemini_native_adapterre  r   r;   r  r   r	   r>   r?  r`  r=   r?   r@   r   r   rj  r   rk  rU   agent.models_devrm  r   r   r@  r   fromkeysr   r   r   ).rs   rY   r^   rJ   r   rM   rN   rO   rP   r   rd   re   r   r
  rb  rt   r  r  ru   r  rw   re  
probe_basetierr  _mr  chosen_baser_  r   rj  api_key_for_prober  r   rk  curatedr  mdev_modelsrm  seenrO  mergedry   rz   rf   rc  s.    `                                           @r'   _model_flow_api_key_providerr  	  s   //////                                   ,G-4-EMg&q))2G+1rL L&  $}R((=BIb",=,= 	E	 */;  L%   h<	%EEEEEEE 	% 	% 	% $	%(12220<D|,,," .9\/R44.- 
 %$\:>>Dv~~B   ;   2   ,---:   9   <   BCCCv~~.////
 KLLLGGG L R$}\22Qbib6Q6Q 	""7++1rB266*%%+,,2244::<<KK"266*#5#5#;<<BBDD 	 	 	D	!?W%?Ne
 +>:: 	6;.88\8N<555$	=.===>>DDFFHH!8, 	 	 	GGGHHH	  	* 	*&&'>?? *c    |X666!) j  ------;;;;;;(Ww-V]]7-C-C-CTV	..)N  JJ  	 	 	<s<<===WXXXJJJJJJ	  	HFS__FFFGGG		&	&??????(Ww-V]]7-C-C-CTV
 /.%#
 
 


  	KIS__IIIJJJ		 	 666666(Ww-V]]7-C-C-CTV"&&{B77&&'8.II 	$JOS__OOW\OOOPPPP "K@@@@@@11+>>    77;777!+..
  , ,Awwyy,,"))!,,,+++TZTTTUUUU$
 sS__sss   #&&{B77 	<<<<<<--k::KK 	 	 	D	  !	  	)77;777k**  , ,Awwyy,,a(((+++#

(
PS__PPPQQQQ 	W** JkS__kkk    !- !*19g&&&r  +*+<nMMK s;//3w<<??(
SZSSSSSTTTT$
 sS__sss  
 555
 
 
 
 
EO
 
 

 43KOO$--'I'Iz'I'I'IIIJJ
 **'(+(
 
 
	^,,2244HH!8, 	 	 	HHH	  99922;IIH8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j(uEEEE999 7 7X N NE*IIj$'''CFxFFw|FFFGGGGGls   $B+ +B:9B:B!J< <
K	K	%L* *!MM,N: :O,?#O''O,S% %
S21S2
W 
W)(W)2!_ _*)_*c                   ddl m} ddlm}m}m} ddlm}m}m	}m
}	 ddlm}
 ddlm}  |            }d}	 ddlm}m}m}  |            }|r ||          rd	}n# t$          $ r Y nw xY wd}|r ||          r|sd	}t'          |          r| p|}| }|r|rvdd
lm} ddlm} d}|d         j        D ]<}t1          j        |d                                          |k    r ||          }|r n=t7          d|dd          d|            n|rt7          d           t7                       t9          d          }|dk    rd	}n|dk    rdS |rt7                       t7          d           t7                       t7          d           t7          d           t7          d           t7                       	 t;          d                                          }n&# t<          t>          f$ r t7                       Y dS w xY w|dk    r ||          sdS n|dk    rt7                       t7          d           t7                       ddl m!} 	  |d                                          }n&# t<          t>          f$ r t7                       Y dS w xY w|st7          d            dS  |	||!           t7          d"           nt7          d#           dS t7                       |
"                    dg           }|r |||d$          }n<	 t;          d%                                          }n# t<          t>          f$ r d}Y nw xY w|r ||            |            }|"                    d&          }tG          |tH                    s|rd'|ini }||d&<   d|d(<   |%                    d)d           tM          |            ||            |             t7          d*| d+           dS t7          d,           dS )-uR   Flow for Anthropic provider — OAuth subscription, API key, or Claude Code creds.r   )_run_anthropic_oauth_flowr  )r   rd   re   save_anthropic_api_keyr   )get_anthropic_keyF)read_claude_code_credentialsis_claude_code_token_valid_is_oauth_tokenTr  )r   r   	anthropicz  Anthropic credentials: Nr  r  u.     Claude Code credentials: ✓ (auto-detected)zAnthropic credentials:r/   r0   r,  z0    1. Claude Pro/Max subscription (OAuth login)z(    2. Anthropic API key (pay-per-token)r  r6   r7   r8   z>  Get an API key at: https://platform.claude.com/settings/keysr  z  API key (sk-ant-...): r  )save_fnr  r"  )r^   r`   z-Model name (e.g., claude-sonnet-4-20250514): rf   rg   rh   r   rm   z (via Anthropic)rn   )'ro   r  r   rM   rN   rO   rq   r   rd   re   r  rr   r   r  agent.anthropic_adapterr  r  r  r   r   r  r  r   rW   r  r  r>   r;   rG   r=   r?   r@   r>  r  r   r   r   r   r   ) rs   r^   r  rM   rN   rO   r   rd   re   r  r   r  ru   cc_availabler  r  r  cc_credsexisting_is_stale_oauth	has_creds
needs_authr  r   r$  varrF   r  rS   r  ry   rz   rf   s                                    r'   _model_flow_anthropicr    s   999999         
            322222 211111$$&&LL	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 0/11 	 228<< 	 L    $ '55 'l '"&l##C,C(CTIJ  	DIIIIII999999 M(5F  9S"%%++--==$?$?$D$DM$ UL",=UUmUU     	DBCCC01IJJXJJxF  &/000@AAA8999o	/006688FF!8, 	 	 	GGGFF	 S==,,^<<  s]]GGGRSSSGGGEEEEEE../IJJPPRR%x0     n%%%""7NCCCC()))) .!!!F	GGG "%%k266J 
**'(
 
 
	LMMSSUUHH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j		*d###(///CAxAAABBBBBlsG   #A 
A'&A'7!G G<;G<I) )JJ!L( (L>=L>)r   r	   r   r	   r
   r   )r)   r	   r
   r	   )r   )rU   r	   r}   r   r
   r   )r   N)r  r	   r
   r	   )__doc__
__future__r   r   r  r  rq   r   r(   rG   r{   r   r   r   r   r  r  r  rT  r  r  r  r  r  r  r&  rJ  rV  r`  r  r  r'  r|   r'   <module>r     s   ( # " " " " "  				     > > > > > > 2 2 2 2 2 2j# # # #LA A A AHF F F FR- R- R- R-j_ _ _ _BV V V VpOT O O O O Ob. . . .`35 35 35 35l] ] ]@n n n n`~/ ~/ ~/@E E E ENsD sD sD sDj[ [ [ [zp p p pd^ ^ ^ ^@z z z zze e e eN7, 7, 7, 7,tk k k kZ	U U U U U Ur|   