
    sj                   >   d Z ddlmZ ddlmZ ddlZddlZddlZddlZ	ddl
mZ ddlmZ dZd5dZd6dZd7dZddd8dZd9dZd:dZd;dZd:dZd:d Zd<d!Zd:d"Zd:dd#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:d0Z&d=d2Z'd:d3Z(d:d4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.
    )annotations)
line_inputN) clear_model_endpoint_credentials)custom_provider_slug)	us.eu.ap.apac.jp.ca.sa.me.af.region_namestrreturnc                t    | pd                                 }dD ]\  }}|                    |          r|c S dS )zJMap an AWS region name to its inference-profile geo prefix ('' = unknown). ))r   )zus-us_gov)r   )zeu-)r	   )zap-)r   )zca-)r   )zsa-)r   )zme-)r   )zaf-)lower
startswith)r   rgeoregion_prefixess       @/home/agent/.hermes/hermes-agent/hermes_cli/model_setup_flows.pybedrock_region_geo_prefixr   ,   sW    		!!##A! 
 
_ <<(( 	JJJ	2    model_idboolc                    | pd                                 t          fdt          D             d          }|                    d          rdS t	          |          }|sdS |dk    r|dv S ||k    S )a-  True when *model_id* can be invoked from *region_name*'s endpoint.

    Bare foundation-model ids and ``global.*`` profiles route from anywhere.
    Geo-prefixed inference profiles (``us.*``, ``eu.*``, ...) only route from
    endpoints in their own geography. Unknown region shapes hide nothing.
    r   c              3  F   K   | ]}                     |          |V  d S Nr   .0pmids     r   	<genexpr>z5bedrock_model_routable_from_region.<locals>.<genexpr>E   s4      MMa3>>!;L;LMMMMMMMr   Nglobal.Tr	   )r	   r
   r   )r   nextBEDROCK_GEO_PREFIXESr   r   )r   r   matched_geor   r'   s       @r   "bedrock_model_routable_from_regionr-   =   s     >r
 
 
"
"CMMMM#7MMMtTTKcnnY77t
#K
0
0C t
e||555#r   provider_idtuple[str, str]c                &    ddl m}  || |          S )zCResolve an existing wizard credential without changing its storage.r   ) _resolve_api_key_provider_secret)hermes_cli.authr1   )r.   pconfigr1   s      r    _existing_api_key_for_model_flowr4   Q   s'    @@@@@@++KAAAr   r   provider_namebase_urlr6   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_poolNr5   Fsourcemodel_configTid)removed_ids)agent.credential_poolr:   r;   r2   r<   r=   
isinstancedictitemsr   r   listgetappend	Exception)r7   r6   r:   r;   r<   r=   active_pool_keypoolspool_keyentriesretainedrA   changedentryentry_ids                  r   /_prune_replaced_custom_model_config_credentialsrR   X   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2rY   3rZ   rX   )	hermes_cli.setuprW   printrI   	enumerateinputstripKeyboardInterruptEOFError)rS   choicesrW   idxilabelmarkerchoices           r   _prompt_auth_credentials_choicerq      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dd	          }t          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
openrouter
OpenRouterapi_key)OPENROUTER_API_KEYr@   name	auth_typeapi_key_env_varsz&Get one at: https://openrouter.ai/keysr.   existing_sourceN)	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providerr7   chat_completionsapi_modeFclear_api_modeDefault model set to: z (via OpenRouter)
No change.)hermes_cli.mainrt   hermes_constantsru   r2   rv   rw   rx   ry   r4   re   hermes_cli.modelsr   r   hermes_cli.configr   r   rG   rC   rD   r   )configr   rt   ru   rv   rw   rx   ry   r3   existing_keyr   	_resolvedabortr   r   openrouter_modelsr   selectedr   r   cfgr   s                         r   _model_flow_openrouterr      sh   //////444444            n0	  G %E\SZ$[$[!L/ 6777& '	  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r   r   presetrD   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_modelsr[   start    r_   r   :r   
aggregatorz  Aggregator:  N)re   rf   rG   )r   r   rl   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                   ddl m} ddlm} ddlm}m}m}m} ddl	m
} |d         }	 |d          pd}
|
s,t          d	           t          d
           t                        ||	|
d          \  }}|rdS ddlm}m}  |d          } |dd          } ||||          }|r ||           ddl	m}m}  |            }|                    d          }t%          |t&                    s|rd|ini }||d<   d|d<   ||d<   d|d<    ||            |             t          d| d           dS t          d           dS )zIVercel AI Gateway provider: ensure API key, then pick model with pricing.r   )AI_GATEWAY_BASE_URLrs   PROVIDER_REGISTRYrw   rx   ry   )get_env_valuez
ai-gatewayAI_GATEWAY_API_KEYr   z^Create API key here: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai-gateway&title=AI+Gatewayz/Add a payment method to get $5 in free credits.)r.   N)ai_gateway_model_idsr   Tr   )r   r   r   r   r   r   r7   r   r   r   z (via Vercel AI Gateway)r   )r   r   r   rt   r2   r   rw   rx   ry   r   r   re   r   r   r   r   r   rG   rC   rD   )r   r   r   rt   r   rw   rx   ry   r   r3   r   r   r   r   r   models_listr   r   r   r   r   r   s                         r   _model_flow_ai_gatewayr     sC   444444//////            0/////  -G =!566<"L l	
 	
 	
 	?@@@&w,WWWIu PPPPPPPP&&T:::K&&|4HHHG&&='  H  8$$$>>>>>>>>kmm  %&& 	!*/7Y&&RE CL(j/j.jCIxIIIJJJJJlr   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   rx   ry   r   )normalize_moa_configmoapresetszCNo MoA presets configured. Run `hermes moa configure <name>` first.Ndefault_presetr   r   r   r   r   r   u     ← defaultz  (agg , z refs)rV   z"Select a Mixture of Agents preset:r[   r\   r]   r^   r_   z  Choice [1-]: r   r   Tr   r7   r   z (via Mixture of Agents)) r2   rx   ry   r   r   r   hermes_cli.moa_configr   rC   rD   rG   re   rF   keyslenrH   indexrd   rW   rI   rf   rg   rh   ri   rj   maxminint
ValueErrorr   popr   )r   r   rx   ry   r   r   r   r   r   namesdefault_namerowsnr   	agg_label	ref_countsuffixdefault_idxrW   rl   rm   rowro   rawselected_namer   r   r   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_staterw   rx   _update_config_for_provider resolve_nous_runtime_credentials	AuthErrorformat_auth_error_login_nousr   )r   r   r   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.r7   r|   )r   r   unavailable_modelsr   unavailable_messager   r   r   r   r   r   OPENAI_BASE_URLOPENAI_API_KEYr   z (via Nous Portal)r   )-r2   r   rw   rx   r   r   r   r   r   r   r   r   r   r   r   hermes_cli.nous_subscriptionr   rG   re   argparse	Namespacegetattrr   rI   
SystemExitr   r   r   r   r   r   r   rC   relogin_requiredr   hermes_cli.nous_accountr   r   r   rstripr   rD   rh   r   r   )0r   r   argsr   rw   rx   r   r   r   r   r   r   r   r   r   r   r   state	mock_args
_refreshedexcr   r   r   r   r   r   r   credsreloginmsg	login_excr   r   refreshed_creds_nous_portal_url_nous_stater   r   r   r   _account_infor   _urlr   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_statusrw   rx   r   _login_openai_codexr   DEFAULT_CODEX_BASE_URL)get_codex_model_ids	logged_inu     OpenAI Codex credentials: ✓zOpenAI Codex credentials:rY   z&Starting a fresh OpenAI Codex login...zopenai-codexTforce_new_loginr   Nr   zLogin failed.rZ   z/Not logged into OpenAI Codex. Starting login...r|   )!resolve_codex_runtime_credentials)r   r   r   r   r   r   r   z (via OpenAI Codex)r   )r2   r  rw   rx   r   r  r   r  hermes_cli.codex_modelsr  rG   re   rq   r   r  r  rI   r   )r   r   r  rw   rx   r   r  r   r  r  statusrp   r	  r  _codex_token_codex_statusr   _codex_credscodex_modelsr   s                       r   _model_flow_openai_codexr(  p  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          	     J   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 |d          } |||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_statusrw   rx   r   %resolve_xai_oauth_runtime_credentials_login_xai_oauthDEFAULT_XAI_OAUTH_BASE_URLr   )provider_model_idsr  u8     xAI Grok OAuth (SuperGrok / Premium+) credentials: ✓z2xAI Grok OAuth (SuperGrok / Premium+) credentials:rY   z#Starting a fresh xAI OAuth login...r   Fr   N)r   r   z	xai-oauthTr  r   r   rZ   zHNot logged into xAI Grok OAuth (SuperGrok / Premium+). Starting login...r7   r   r   zgrok-4.6)r   r   u.    (via xAI Grok OAuth — SuperGrok / Premium+)r   )r2   r*  rw   rx   r   r+  r,  r-  r   r   r.  rG   re   rq   r   r  r   r  r  rI   rh   r  )_configr   r  r*  rw   rx   r   r+  r,  r-  r   r.  r#  rp   r	  r  r7   r  modelsr   s                       r   _model_flow_xai_oauthr1    s   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 544444&&((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     ,,F&&v]=s\bOrvVWyyhrtttH 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_credentialsrw   rx   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_expiringr|   r7   zqwen3-coder-plusz
qwen-oauthr   r   r   r   z (via Qwen OAuth)r   )r   r3  r2   r4  r5  rw   rx   r   r6  r   r8  rG   re   rI   rF   )r/  r   r3  r4  r5  rw   rx   r   r6  r8  r#  r9  r0  r  r   r   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   rw   rx   r   )resolve_minimax_oauth_runtime_credentialsr   r   _login_minimax_oauthr   zminimax-oauthr   z0Not logged into MiniMax. Starting OAuth login...regionNglobalr   Fr   r   )rA  r   r   r   r   _PROVIDER_MODELSr7   )r   r   u   ✓ Using MiniMax model: )r2   r   rw   rx   r   r?  r   r   r@  r   rG   re   r   r  r  r   r  rI   r   rD  )r   r   r  r   rw   rx   r   r?  r   r   r@  r   r  r	  r  r  rD  r   r   s                      r   _model_flow_minimax_oauthrE  I  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
}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           	 t3          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,t;          |                    d)          pg            d-           n}t          d.|                    d+           d/           |                    d0          rB|d0         }|                    d          rt          d1|            nt          d2|            |                     d3          }d}t=          |t>                    r6tA          |                    d4          pd                                          } |||5          }|rt          d6|            nt          d7           d}|                    d)          pg }	 t;          |          d8k    r{t          d9|d                     t3          d:                                                                          }|d"v r
|d         }nt!          d;                                          }nt;          |          d8k    rt          d<           tC          |d8          D ]\  }}t          d=| d>|            t3          d?t;          |           d@                                          }|"                                rCd8tG          |          cxk    rt;          |          k    rn n|tG          |          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	 tG          | $                    dCd          $                    dDdE          $                    dFdE                    }#|#dk    rd}#n%# tJ          $ r t          dG|  dH           d}#Y nw xY wd}$|rdtL          j'        (                    |          }%|%j)        pd}&|%j*        r|& dI|%j*         }& ||&          }$ |
|$|           t          dJ|$            |r ||            |            }'|'                    d3          }(t=          |(t>                    s|(rdK|(ini }(|(|'d3<   dL|(dM<   ||(dN<   |$r	dO|$ dP|(dQ<   |r||(d4<   n|(+                    d4d            |	|'            |             t?          |(          | d3<   t          dR| dS| dT           n|s|r
 |             |                     d3          })t=          |)t>                    s|)rdK|)ini })dL|)dM<   ||)dN<   |$r	dO|$ dP|)dQ<   |r||)d4<   n|)+                    d4d           |)| d3<   t          dU            ||||pd|#|"||$V           tY          ||"W           dS )XzCustom 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   )custom_endpoint_key_envr   r   r   r   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 r"    )r%   h
_url_lowers     r   r(   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.r0  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: r   r   )current_api_modez  API mode: z  API mode: auto-detectr[   z  Detected model: z  Use this model? [Y/n]: z&Model name (e.g. gpt-4, llama-3-70b): z  Available models:r   r_   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._z  API key saved to .env as r   customr   r7   z${}r|   r    (via )zFEndpoint saved. Use `/model` in chat or `hermes model` to set a model.)context_lengthr   r   key_envr5   )-r   rG  rH  rI  r2   rx   ry   r   rJ  r   r   r   r   hermes_cli.secret_promptrL  re   r   rh   ri   rj   r   r  r   anyendswithrg   r   r]  rG   r   rC   rD   r   rf   isdigitr   replacer   urllibparseurlparsehostnameportr   rR   )+r   rG  rH  rI  rx   ry   rJ  r   r   r   r   rL  current_urlcurrent_keyr7   r|   effective_urleffective_key_looks_local_add_v1r]  probe	suggestedr  rc  r   
model_namedetected_modelsconfirmrm   mpickcontext_length_strr   display_namerm  custom_key_env_parsed	_identityr   r   _caller_modelrY  s+                                             @r   _model_flow_customr    s    nmmmmmmmmmGGGGGGGG              >=====- 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/

'(PQQWWYY

!!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];

 "!
#$LMMSSUUJ'F
 

%'' 	
 +*=99!"D<"D"D"DEEKKMM]Q]x(   n N "
	" "**333e$$e$$ N
 ""!% 	" 	" 	"W-?WWWXXX!NNN	" N >,''66$*	< 	6$55w|55I00;;~}555<N<<=== ,X:&&& kmm  %&& 	!*/7Y&&RE CL$j)j 	87^777E) 	( (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! 	@'?^'?'?'?M)$ 	0(0M*%%j$///'wVWWW b%    4"     sK   AC) ) DD3H7 7II=GY  Y?>Y?A[ [=<[=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# t:          $ 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          },tG          |,j$                  }-|,j%        pd	}.|.r^|.dk    rdnd}/t!          dV|/            |,j&        rt!          dW|,j&         dC           |-r t!          dXtO          |-           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           tQ          |-ddc         dde          D ]\  }3}4t!          df|3dgdh|4            tO          |-          dck    r#t!          ditO          |-          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)                                rQddtU          |5          cxk    r!tW          tO          |-          dc          k    rn n|-tU          |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<   t[          |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   r   r   r   r   )azure_detectr   r   zazure-foundryr7   r   r   	auth_moder|   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:  r   zOpenAI-stylezAnthropic-stylez  Current API mode:  entra_idz1  Current auth mode: Microsoft Entra ID (keyless)z  Current auth mode: API key (NrM  z...)zhe.g. https://<resource>.openai.azure.com/openai/v1 or https://<resource>.services.ai.azure.com/anthropiczAPI endpoint URL [r   rQ  r   z$No endpoint URL provided. Cancelled.rR  rT  rU  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.rb   ra   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      $@)r   timeout_secondsokenv_sourcesr   zdefault chainu   ✓ Entra ID token acquired (z, scope=rl  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.)r   u0   ⚠ Could not build token provider for probing: rK  rO  rN  requiredzNo API key provided. Cancelled.u;   ◐ Probing endpoint to auto-detect transport and models...)r|   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:   r[   r   r^   z>2r_   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.r   r   rm  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: rd  z tokenszA    Context length: not auto-detected (will fall back at runtime)).r2   rx   ry   r   r   r   r   r   
hermes_clir  rG   rC   rD   r   rh   r   re   r   ri   rj   r  r   rg   agent.azure_identity_adapterr  r  r  r  r  ImportErrorjoinrI   ro  rL  detectrF   r0  r   reasonr   rf   rr  r   r   lookup_context_lengthr   )>r   r   rx   ry   r   r   r   r   r  r  current_base_urlrc  current_auth_mode
_cur_entracurrent_entracurrent_api_key_lbl_placeholderr7   r{  _auth_defaultauth_choice	use_entraauth_mode_labelr|  entra_overridesr  entra_scoper  r  r  r  r  r  _persisted_scope_overrider/  infor  tagerrr  ansrL  r|   	detectiondiscovered_modelsr   
mode_labeldefault_choicemode_choiceeffective_modelrm   r'   r  r  ctx_lenr   r   clean_entrakeyval
auth_labels>                                                                 r   _model_flow_azure_foundryr  r  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	}m
}	 ddlm}
m} ddlm}m}m}m}m} |d         }|d         }|                    d	d
          }|                    dd
          }|                    dd
          }|                    dd
          <|                    d          pd
                                }|s"|r t,          j                            |d
          } |||          }|                    dd          }t1          |t2                    r|                                dv}g }d}|                    di           } || |
|                    }t1          |t6                    rd |D             }nt1          |t8                    rg }|D ]}t1          |t6                    rLt3          |                    d          p|                    d          pd
                                          }n8t1          |t2                    r!t3          |                                          nd
}|r|                    |           t=          d|            t=          d|            <rt=          d<            t=                       |s*|p<r<gng }t=          dt?          |                      nt=          d           ddi} |r|| d	<   |                                dk    s*|                                                                dk    rdnd}! ||                    d                    pi }" |||           }#tA          |#          D ] ;tC          ;fd!|"D                       r|#;= !|#"                    |"           tC          d" |"D                       }$|r7|$s5tA          |#          D ];;                                d#k    r|#;= d$| |#d%<    ||!||#pd&'          }%|%r|#pd&n|"pd&}&|}'|%r7|r|r|}(d}n< ||d|&(          }(|(g k    }|( || ||          fd)|&i| }(d}n |||fd)|&i| }(d}|'r|n|rg n|(p|}|(r)	 dd*lm#})  |)||(||"pd&+           n# tH          $ r Y nw xY w|rd}*<r<|v r|%                    <          }*t=          d,t?          |           d-           	 dd.l&m'}+ <fd/|D             d0gz   }, |+d1| d2|,|*d3d4          }-t=                       |-dk     s|-t?          |          k    rt=          d5           d&S ||-         }.n# tP          tR          tT          tV          j,        f$ r) t[          |d6          D ]&\  }/}0|0<k    rd7nd
}1t=          d8|/ d9|0 |1            't=          d8t?          |          d6z    d:           t=                       	 t]          d;t?          |          d6z    d<                                          }2|2st=          d5           Y d&S t_          |2          d6z
  }-|-dk     s|-t?          |          k    rt=          d5           Y d&S ||-         }.n.# t`          tb          td          f$ r t=          d=           Y Y d&S w xY wY nw xY w<ra|s_t=          d>           	 tg          d?< d<                                          p<}.n# tb          td          f$ r t=          d=           Y d&S w xY wt=          d@           	 tg          dA                                          }.n'# tb          td          f$ r t=          d=           Y d&S w xY w|.st=          dB           d&S  ||.            |            }3|3                    d          }4t1          |4t6                    s|4rdC|4ini }4|4|3d<   |r@ti          ||          |4dD<   |45                    dd&           |45                    dd&           nd|4dD<    |||          |4d<   |r||4d<   |                    d	d
          }5|5r|5|4d	<   n|45                    d	d&            |	|3            |             |rs |            }3|3                    dE          }6t1          |6t6                    r=|6                    |          }7t1          |7t6                    r|.|7dF<   t3          |                    dGd
          pd
                                          }8t3          |                    dd
          pd
                                          }9tm          |8p|9          }:|:r>|r<t3          |7                    dd
          pd
                                          s||7d<   |r<t3          |7                    dd
          pd
                                          s||7d<   |6|3dE<    |	|3           n ||||.|H           t=          dI|.            t=          dJ| dK| dL           d&S )Ma]  Handle a named custom provider from config.yaml custom_providers list.

    Probes the endpoint's model catalog to let the user pick a model, using
    native ``/api/tags`` for endpoints conservatively identified as Ollama.
    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_valuerI  r   )r   normalize_extra_headersr   )_entry_models_discovered_models_config_is_allowlist)r8  fetch_ollama_local_models_get_ollama_native_headers_normalize_openai_base_url should_use_ollama_native_catalogr   r7   r   r   r|   rn  r   provider_keydiscover_modelsT>   0nofalseFr0  c                v    g | ]6}|d vt          |                                          't          |          7S )>   __discovered_model_catalog____explicit_model_allowlist__)r   rh   r%   r  s     r   
<listcomp>z,_model_flow_named_custom.<locals>.<listcomp>  sX     
 
 
    A	 FF  r   r@   z  Provider: z  URL:      z  Current:  z2Using configured models (discover_models: false): zFetching available models...r   g       @ollamari  extra_headers)r|   c              3  l   K   | ].}                                 |                                 k    V  /d S r"   r   )r%   existingr  s     r   r(   z+_model_flow_named_custom.<locals>.<genexpr>F  s:      QQx399;;(.."2"22QQQQQQr   c              3  F   K   | ]}|                                 d k    V  dS )authorizationNr  )r%   r  s     r   r(   z+_model_flow_named_custom.<locals>.<genexpr>I  s@       '
 '
/2CIIKK?*'
 '
 '
 '
 '
 '
r   r  zBearer AuthorizationN)headers)r   r  r  )!_save_discovered_models_to_config)r   r  zFound z model(s):
)curses_radiolistc                *    g | ]}|k    r| d n|S )
 (current)rW  )r%   r  saved_models     r   r  z,_model_flow_named_custom.<locals>.<listcomp>  s>       @AA$4$41    !  r   rU   zSelect model from r   )r   cancel_returns
searchabler  r[   r  r^   r_   z. Cancelz
Choice [1-r   rQ  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.r   r   	providersdefault_modelapi_key_ref)r   u   
✅ Model set to: z   Provider: ra  rl  )7r   r  r  rI  r2   rx   ry   r   r   r  r   hermes_cli.model_switchr  r  r   r8  r  r  r  r  rG   rh   osenvironrC   r   r   rD   rF   rH   re   r   tuplerp  updater  rI   r   hermes_cli.curses_uir  r  NotImplementedErrorOSError
subprocessSubprocessErrorrf   rg   r   r   ri   rj   r   r   r   r   )=r   provider_infor  r  rI  rx   ry   r   r  r   r  r  r8  r  r  r  r  r   r7   r   r|   rn  r  config_api_keydiscoverconfigured_modelsnative_catalog_empty
cfg_modelsexplicit_catalogmodel_entryr   r0  fetch_kwargsnative_catalog_providerr  candidate_headerscaller_has_authorization
use_nativenative_headers_argexplicit_allowlistlive_modelsr  r   r  
menu_itemsrl   r  rm   r  r   r  r   r   custom_api_modeproviders_cfgprovider_entryoriginal_api_key_reforiginal_api_keyhad_inline_api_keyr  r  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SSSSSSSSSS                      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22,,];;  *d## 3
 

 
 
 
J	%	% 3% 	3 	3K+t,, \{t44V8P8PVTVWW]]__7A+s7S7S[3{++11333Y[ 3!((222	


   	
#
#
#$$$ ,*[**+++	GGG W #L'K}}6{{ 	
 	
 	
 	

 	,---!3' 	0'/L$ !!##x//4::<<3E3E3G3G83S3S H 	 
 0/0A0A/0R0RSSYWY66xQQQ*++ 	+ 	+CQQQQ=QQQQQ +%c*  ///#& '
 '
6C'
 '
 '
 $
 $
   	E3 	E.// / /99;;/11)#.1D71D1Do.55#X7H7PD
 
 

 ;Ea.6$=K`\`- 	) 1$5 1/',$$77.  
 (3b'8$&"2"2228<<# # !3# '	# #K ,1(** +=AM K $)  "4 $42!2 	  	      21%)1T	          ; 	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%%% 
	& 
 1 5666	#$C;$C$C$CDDJJLL[P[JJ!8, 	 	 	.!!!FF	 	PQQQ	#N3399;;JJ!8, 	 	 	.!!!FF	  	2333F z"""
+--CGGGEeT"" &+3E""G 
.0|DD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	
-
-
-...	
-$
-
-(
-
-
-.....s   Q4 4
R RA"T3 )T3 3BY??AY:YYY?&Y94Y?8Y99Y?>Y?'Z> > ["!["5!\  \;:\;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<	 tM          d4                                          }(n# t2          t4          f$ r d}(Y nw xY w|(r@ ||(|$|-          p|(}( |            }) ||)          }* ||(|$|-          }+d},|+r t-          d5|( d6            ||+|*7          }, ||(            |            }-|-                    d8          }.tO          |.tP                    s|.rd9|.ini }.|.|-d8<   ||.d:<   |#|.d;<    ||(|$|-          |.d<<   tS          |.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   rw   rx   ry   $resolve_api_key_provider_credentials)r   r   r   )rD  r8  fetch_github_model_cataloggithub_model_reasoning_effortscopilot_model_api_modenormalize_copilot_model_idcopilotr|   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]: Nra   )copilot_device_code_loginCOPILOT_GITHUB_TOKENz  Copilot token saved.z  Login cancelled or failed.z  Login failed: rb   rK  z   Token (COPILOT_GITHUB_TOKEN):   Cancelled.)validate_copilot_tokenu     ✗ z  Token saved.>   GH_TOKENGITHUB_TOKENformat_secret_source_suffixz  GitHub token: rM  u	   ... ✓ (rl  zgh auth tokenu*     GitHub token: ✓ (from `gh auth token`)u     GitHub token: ✓c                d    g | ]-}|                     d           |                     d d          .S r@   r   rG   r%   items     r   r  z'_model_flow_copilot.<locals>.<listcomp>v  s5    BBB488D>>B$		BBBr   catalogr|   c                    g | ]}||S rW  rW  )r%   r   s     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  r^   z supports reasoning controls.)current_effortr   r   r   r7   r   Fr   r   rk  nonez"Reasoning disabled for this model.zReasoning effort set to: r   )+r   r  r  r  r2   r   rw   rx   ry   r  r   r   r   r   r   rD  r8  r  r  r  r  rG   re   rg   rh   ri   rj   hermes_cli.copilot_authr  rI   ro  rL  r   r  hermes_cli.env_loaderr$  inference_base_urlr   r   rC   rD   r   r   )/r   r   r  r  r  r   rw   rx   ry   r  r   r   r   rD  r8  r  r  r  r  r.   r3   r  r|   r>   rp   r  tokenr  rL  new_keyr   validr  r$  	bw_suffixeffective_baser+  r	  normalized_current_model
model_listr   initial_cfgr1  reasoning_effortsselected_effortr   r   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(+#
 
 
	!.117799HH!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   rw   rx   ry   $get_external_process_provider_statusr  -resolve_external_process_provider_credentials)rD  r  r  r   zcopilot-acpresolved_commandcommandr  r7   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   r|   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/  r0  r!  r  r   r   r   r   r   r   Fr   r   rk  rl  )r2   r   rw   rx   ry   rB  r  rC  r   rD  r  r  r   r   r   rG   r5  re   rI   r   r   rh   ri   rj   rC   rD   r   r   )r   r   r   rw   rx   ry   rB  r  rC  rD  r  r  r   r   r.   r3   r#  rD  r:  r  r  catalog_api_keycatalog_credsr+  r;  r<  r   r   r   s                                r   _model_flow_copilot_acprI    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(++
 
 
	!.117799HH!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                   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        pd}t!          ||          \  }} |||||          \  }}|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# t.          t0          f$ r d	}Y nw xY w|r ||            |
            }|                    d          }t3          |t4                    s|rd|ini }||d<   ||d<   ||d<   |                    dd	           t9          |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   rs   )r   KIMI_CODE_BASE_URLrw   rx   ry   r  rC  zkimi-codingr   r   Nzsk-kimi-u$     Detected Kimi Coding Plan key → u     Using Moonshot endpoint → moonshotr!  zEnter model name: r   r   r   r7   r   Fr   zKimi CodingMoonshotr   rk  rl  r   )r   rt   r2   r   rK  rw   rx   ry   r   r   r   r   r   r   rD  base_url_env_varr4   r   re   r5  rG   r   rh   ri   rj   rC   rD   r   r   )r   r   rt   r   rK  rw   rx   ry   r   r   r   r   rD  r.   r3   base_url_envr   r   r   is_coding_planr:  r<  r   r   r   endpoint_labels                             r   _model_flow_kimirR  D  sM    0/////                         322222K,G+1rL %E[RY$Z$Z!L/)/'	  L%   ",,Z88N A+E^EEFFFF 3?~??@@@ )l33 )|R(((	GGG "%%~&Umm:WYZZJ **'(+(
 
 
	!"677==??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   =!D D54D5c                   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        pd}t'          ||          \  }} |||||          \  }}|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_regionrt   _prompt_provider_choice_stepfun_base_url_for_regionr   r  )rD  r8  stepfunr   r   Nr   r7   internationalzInternational (rl  chinazChina (u     ← currently active)rZ   rU   c                    g | ]\  }}|S rW  rW  )r%   rh  rn   s      r   r  z'_model_flow_stepfun.<locals>.<listcomp>  s    )P)P)PHAu%)P)P)Pr   rZ   r   r-   model(s) from  APIz$  Could not auto-detect models from u,    API — showing Step Plan fallback catalog.r!  r  r   r   r   Fr   r   rk  )&r   rT  rt   rU  rV  r2   r   rw   rx   ry   r   r   r   r   r   r   rD  r8  rN  r4   r  getenvrG   rC   rD   r   rh   r5  insertrH   re   r   r   r   ri   rj   r   r   )%r   r   rT  rt   rU  rV  r   rw   rx   ry   r   r   r   r   rD  r8  r.   r3   rO  r   r   r   current_baser  current_regionregion_choicesordered_regions
region_keyrn   
region_idxselected_regionr:  r	  r<  r   r   r   s%                                        r   _model_flow_stepfunrf    s(   }}}}}}}}}}}}                       EDDDDDDDK,G+1rL$D[RY$Z$Z!L/)/'	  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  
  **'(+(
 
 
	!.117799HH!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   !I; ;JJc                   ddl m}m}m} ddlm}m}m} ddlm	}	 d| d}
ddl m
}m}  |dd	d
d          } |d|          \  }}|r1ddlm}  ||p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|rE ||            |            }|                    d          }t/          |t0                    s|rd|ini }||d<   d|d<   t3          |d d !           |                    d"          }t/          |t0                    si }||d"<   |                    d#          }t/          |t0                    si }|
|d$<   d|d%<   ||d#<   |                    di           }t/          |t0                    si }||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   rw   rx   ry   )r   r   r   rC  zhttps://bedrock-mantle.z.api.aws/v1)r1   rv   bedrockBedrockr|   )AWS_BEARER_TOKEN_BEDROCKr~   r#  rk  z  Bedrock API Key: N      ... ✓z  Endpoint: rK  r       ✓ API key saved.
  Showing z curated modelsri  r!    Model ID: r   r   zcustom:bedrock-mantler   T)r   clear_base_urlr  zbedrock-mantler7   rn  rA    Default model set to: z (via Bedrock API Key, rl    No change.)r2   rw   rx   ry   r   r   r   r   r   rD  r1   rv   r4  r$  re   ro  rL  rh   ri   rj   rG   r   r   rC   rD   r   )r   rA  r   rw   rx   ry   r   r   r   rD  mantle_base_urlr1   rv   bedrock_pconfigr   r   r$  source_suffixrL  r|   r<  r   r   r   r  mantle_entrybedrock_cfgs                              r   _model_flow_bedrock_api_keyry  	  s            
         
 322222CCCCO QPPPPPPP$n6	  O %E$D?% %!L/  &EEEEEE3399
 
 	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 **'%,(
 
 
	!.117799HH!8, 	 	 	HHH	  *8$$$ kmm  %&& 	!*/7Y&&RE CL3j($t	
 	
 	
 	
 GGK((	)T** 	)I(C }}%566,-- 	L#2Z "<Y&2	"# ggi,,+t,, 	K &H$ICSSS&SSSTTT._../////ns$   !B? ?C"!C"-!F F%$F%c                
   !" 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            ||          }|rd}d}g }|D ]h}|d         "t-          "fd|D                       r&t-          "fd|D                       rBt/          "|          sS|                    |           it2          dz   t5                      }|D ]R}|d         "t7          "fd D             d          }|r*|                    "t;          |          d                    Sg }|D ]9}|d         ""                              s"|v r$|                    |           :g d! d@fd%! !fd&}|                    |'           d( |D             }t          d)t;          |           d*t;          |           d+           nJ|                     d,g           }|r!t          d-t;          |           d.           nt          d/           dS |r |||d,d0| d12          }n<	 t!          d3                                          }n# t$          t&          f$ r d}Y nw xY w|r ||            |            }|                     d4          }tC          |tD                    s|rd5|ini }||d4<   d,|d6<   d0| d1|d7<   |#                    d8d           tI          |d9:           |                     d,i           }tC          |tD                    si }||d;<   ||d,<    ||            |             t          d<| d=| d>           dS t          d?           dS )Au$  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   rh  r   rC  )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]: rb   z  Discovering models in rN  )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$   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   )r)   c              3  F   K   | ]}                     |          |V  d S r"   r#   r$   s     r   r(   z&_model_flow_bedrock.<locals>.<genexpr>	  4      JJaq8I8IJJJJJJJr   )	zanthropic.claude-sonnet-4-6zanthropic.claude-opus-4-6zanthropic.claude-haiku-4-5zamazon.nova-prozamazon.nova-litezamazon.nova-microzdeepseek.v3zmeta.llama4-maverickzmeta.llama4-scoutr'   r   r   c                t     t           fdD             d           }|r t          |          d          n S )Nc              3  F   K   | ]}                     |          |V  d S r"   r#   r$   s     r   r(   z8_model_flow_bedrock.<locals>._base_id.<locals>.<genexpr>

  r  r   )r*   r   )r'   _pp_PROFILE_PREFIXESs   ` r   _base_idz%_model_flow_bedrock.<locals>._base_id	
  sF    JJJJ#4JJJDQQC%(13s3xxyy>>c1r   c                    | d         } |          }t                    D ]9\  }}|                    |          rd||                    d          sdnd|fc S :|                    d          rddd|fS ddd|fS )Nr@   r   r)   r[      )rf   r   )r  r'   baserm   rec_RECOMMENDED_BASESr  s        r   	_sort_keyz&_model_flow_bedrock.<locals>._sort_key
  s    D'C8C==D#$677 R R3??3'' Rq3>>)+D+D"K!!!SQQQQR ~~i(( &1a~%q!S>!r   )r  c                    g | ]
}|d          S )r@   rW  r  s     r   r  z'_model_flow_bedrock.<locals>.<listcomp>
  s    ///!ag///r   r-  z text model(s) (filtered from z total)ri  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<  rp  r   r   r   r7   r   Fr   rA  rr  z (via AWS Bedrock, rl  rs  )r'   r   r   r   )%r2   rw   rx   ry   r   r   r   r   rD  agent.bedrock_adapterr{  r|  r}  r~  r  re   r   rh   ri   rj   rg   ry  rp  r-   rH   r+   setr*   addr   r   sortrG   rC   rD   r   r   )#r   r   rw   rx   ry   r   r   rD  r{  r|  r}  r~  auth_varr`  region_inputrA  r  r	  _EXCLUDE_PREFIXES_EXCLUDE_SUBSTRINGSfilteredr  profile_base_idsr  dedupedr  r<  r   r   r   rx  r  r  r  r'   s#                                  @@@@r   _model_flow_bedrockr  	  sm            
 ;:::::::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!"F>"F"F"FGGMMOO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 Z	
 I  	 	AD'C@@@@.?@@@@@ AAAA-@AAAAA 5c6BB OOA 1<?55 	5 	5AD'CJJJJ#4JJJDQQC 5 $$SS^444 	 	AD'CNN#455+++NN1


 

 

	2 	2 	2 	2 	2 	2		" 		" 		" 		" 		" 		" 	###//w///
_s:__c+FVFV___	
 	
 	
 	
 &)))R88
 	X3z??XXX    \   F  **'&NNNN	
 
 
	!.117799HH!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 G21G2!P1 1QQ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   rh  )r   r   r   rC  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   NrA  rB  z  Vertex region [zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-previewzGhttps://aiplatform.googleapis.com/v1beta1/projects/<project>/locations/z/endpoints/openapirS  z@-aiplatform.googleapis.com/v1beta1/projects/<project>/locations/r<  r   r   r   r7   r   Fr   rr  z (via Google Vertex AI, rl  rs  )r2   rw   rx   ry   r   r   r   r   r   rD  rh   re   rG   rC   rD   r   r   ri   rj   r   r   )r   r   rw   rx   ry   r   r   r   rD  sa_pathr   
vertex_cfgcurrent_projectproject_inputr  r`  r  rA  r<  base_url_previewr   r   vcfgs                          r   _model_flow_vertexr  R
  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!"In"I"I"IJJPPRR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   )rU  )ZAI_ENDPOINTSc                     g | ]\  }}}}||fS rW  rW  )r%   rh  urlrn   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 )ra  rl  rW  )r%   rn   r  s      r   r  z(_select_zai_endpoint.<locals>.<listcomp>
  s-    <<<jeS%!!3!!!<<<r   zCustom proxy URLzSelect Z.AI / GLM endpoint:)r   rS   NzCustom base URL [r   rR  M     Invalid URL — must start with http:// or https://. Keeping current value.r[   )r   rU  r2   r  rh   r  rf   r   rH   r   ri   rj   re   r   )r_  rU  r  optionsnormalized_currentr   rl   rh  r  rk   r   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<<	 !"Gl"G"G"GHHNNPPHH!8, 	  	  	 GGG	   	 ""#:;; 	 abbbs###8Q&&s+++s   %C7 7!DDc                r  / 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k    rt'          d           d}n)t)          |          \  }} ||||	          \  }}|rd
S dk    rS|rP	 ddlm} n# t.          $ r d
}Y nw xY w|3t'          d           |r ||          ndpt1          j        |pdd          p|j        } |||          }|dk    rt'                       t'          d           t'          d           t'          d           t'          d           t'                       t'          d           t'          d           t'                       t'          d           t'                       t'          d           d
S |dk    rt'          d           nt'          d           t'                       d}|r  ||          pt1          j        |d          }|s	  |
                                d          pi }t9          |                    d          pd                                                                          k    r6t9          |                    d          pd                                          }n# t.          $ r Y nw xY w|p|j        }dk    r(t?          |          }|r||k    r|r |	||           |}n	 tA          d| d                                          }n'# tB          tD          f$ r t'                       d}Y nw xY w|r5|r3|#                    d           st'          d!           n |	||           |}d"k    rdd#lm$} dd$lm%} |p|r ||          nd}	  |||%          } n5# |$ r-}!t'          d&|!            t'          d'           g } Y d
}!~!nd
}!~!ww xY w| r t'          d(tM          |            d)           n{d*k    rIdd+lm'}" |p|r ||          nd} |"||d,-          } | r t'          d(tM          |            d.           n,d/k    rHdd0lm} |p|r ||          nd}|                    g           }# |||          }$|$r,|$} t'          d(tM          |            d1|j(         d2           ng }%	 dd3l)m*}&  |&          }%n# t.          $ r Y nw xY w|%rd4 |%D             }'tW          |%          } |#D ]T}(|(                                |'vr<| ,                    |(           |'-                    |(                                           Ut'          d(tM          |            d5           n|#} | r t'          d6tM          |            d7           n݉dk    r:|                    g           } | r t'          d6tM          |            d8           n|                    g           }#g }%	 dd3l)m*}&  |&          }%n# t.          $ r Y nw xY w|%r|#rud9 |%D             }'tW          |%          })|#D ]T}(|(                                |'vr<|),                    |(           |'-                    |(                                           U|)} n|%} t'          d(tM          |            d5           n|#r6tM          |#          d:k    r#|#} t'          d6tM          |            d7           n|p|r ||          nd} |||          }$|$rKtM          |$          tM          |#          k    r+|$} t'          d(tM          |            d1|j(         d2           n$|#} | r t'          d6tM          |            d7           d;v rL/fd<| D             }  /|          }tW          t\          /                    d= | D                                 } | r;i }*	 dd>lm0}+  |+          pi }*n# t.          $ r i }*Y nw xY w || ||*||?          },n<	 tA          d@                                          },n# tB          tD          f$ r d
},Y nw xY w|,rӉd;v r /|,          }, ||,            |
            }-|-                    d          }.tc          |.t\                    s|.rdA|.ini }.|.|-d<   |.d<   ||.d<   te          |.dBC           d;v r ||,          |.dD<   n|.3                    dDd
            ||-            |             t'          dE|, dF|j(         dG           d
S t'          dH           d
S )IzCGeneric flow for API-key providers (z.ai, MiniMax, OpenCode, etc.).r   rs   r   r  )rD  r8  opencode_model_api_modenormalize_opencode_model_idr   opencode-freeu<     OpenCode Free is keyless — no API key or account needed.r   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).r   r   r7   zaiz
Base URL [r   rR  r  lmstudio)r   )fetch_lmstudio_models)r|   r7   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)r|   r7   r   z model(s) from Ollama Cloudnovitar7  r[  r\  )list_agentic_modelsc                6    h | ]}|                                 S rW  r  r  s     r   	<setcomp>z/_model_flow_api_key_provider.<locals>.<setcomp>       777a		777r   z" model(s) from models.dev registryro  r   uB    keyless free models — use "Enter custom model name" for others.c                6    h | ]}|                                 S rW  r  r  s     r   r  z/_model_flow_api_key_provider.<locals>.<setcomp>  r  r   rM  >   opencode-goopencode-zenr  c                (    g | ]} |          S rW  rW  )r%   r'   r  r.   s     r   r  z0_model_flow_api_key_provider.<locals>.<listcomp>  s4     
 
 
>A''S99
 
 
r   c              3     K   | ]}||V  	d S r"   rW  )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   r  r   Fr   r   r   rk  rl  r   )4r   rt   r2   r   rw   rx   ry   r   r   r   r   r   r   rD  r8  r  r  r   rN  re   r4   agent.gemini_native_adapterr  rI   r  r]  r5  rG   r   rh   r   r  r   ri   rj   r   r   r  r   r  r   agent.models_devr  rF   rH   r  rD   fromkeysr   rC   r   r   )0r   r.   r   rt   r   rw   rx   ry   r   r   r   r   rD  r8  r  r3   rn  rO  r   r   r   r  
probe_basetierr_  _mr:  chosen_baser  r   r  api_key_for_prober<  r  r  curatedr	  mdev_modelsr  seenr  mergedr   r   r   r   r   r  s0    `                                             @r   _model_flow_api_key_providerr  
  sz   //////                                   ,G-4-EMg&q))2G+1rL o%%LMMM )IV](^(^%o-o#+	
 
 
e  	F 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$	!"B~"B"B"BCCIIKKHH!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   
	'	'
 &))+r::
 	pS__ppp   #&&{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  
 FFF
 
 
 
 
EO
 
 

 43KOO$--'I'Iz'I'I'IIIJJ
  	BBBBBB..{;;ArGG 	 	 	GGG	**'(+(
 
 
	!.117799HH!8, 	 	 	HHH	  JJJ22;IIH8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j(uEEEEJJJ 7 7X N NE*IIj$'''CFxFFw|FFFGGGGGls    B' 'B65B6B!J8 8
KK %L& &!M
	M
(N6 6O(;#O##O(S! !
S.-S.X 
X%$X%_3 3``!`: :aa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<	 tG          d%                                          }n# t<          t>          f$ r d}Y nw xY w|r ||            |            }|"                    d&          }tI          |tJ                    s|rd'|ini }||d&<   d|d(<   |&                    d)d           tO          |            ||            |             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_flowrh  )r   r   r   save_anthropic_api_keyrC  )get_anthropic_keyF)read_claude_code_credentialsis_claude_code_token_valid_is_oauth_tokenTr#  )r   r   	anthropicz  Anthropic credentials: Nrl  rm  u.     Claude Code credentials: ✓ (auto-detected)zAnthropic credentials:rY   rZ   r  z0    1. Claude Pro/Max subscription (OAuth login)z(    2. Anthropic API key (pay-per-token)r  r`   ra   rb   z>  Get an API key at: https://platform.claude.com/settings/keysrK  z  API key (sk-ant-...): r  )save_fnrn  rs  )r   r   z-Model name (e.g., claude-sonnet-4-20250514): r   r   r   r7   r   z (via Anthropic)r   )(r   r  r2   rw   rx   ry   r   r   r   r   r  r   rD  r  agent.anthropic_adapterr  r  r  rI   r   r4  r$  r   r   r  r]  rh   re   rq   rg   ri   rj   ro  rL  rG   r   rC   rD   r   r   ) r   r   r  rw   rx   ry   r   r   r   r  rD  r  r   cc_availabler  r  r  cc_credsexisting_is_stale_oauth	has_creds
needs_authr$  r   rv  varrp   rL  r|   r<  r   r   r   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 
**'(
 
 
	!"QRRXXZZHH!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.   r   r   r/   )r7   r   r6   r   r   r8   )rS   r   r   r   )r   )r   r   r   rD   r   r8   )r   N)r_  r   r   r   )*__doc__
__future__r   hermes_cli.cli_outputr   r   r  r  urllib.parsert  r   r   hermes_cli.providersr   r+   r   r-   r4   rR   rq   r   r   r   r   r  r(  r1  r=  rE  r  r  r  r@  rI  rR  rf  ry  r  r  r  r  r  rW  r   r   <module>r     s*   ( # " " " " " , , , , , ,  				         > > > > > > 5 5 5 5 5 5 
   "   (B B B B 2 2 2 2 2 2j# # # #LD D D DNF F F F3 3 3 3l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p p pfn n n n`d/ d/ d/L	E E E ENsD sD sD sDjY Y Y Yvn n n n`s s s sjK K K K\e e e eN7, 7, 7, 7,tG G G GR
U U U U U Ur   