
    Pmj                   2   d 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d4d
Zd5dZd6dZddd7dZd8dZd9dZd:dZd9dZd9dZd;d Zd9d!Zd9dd"d#Zd9d$Zd;d%Zd& Zd9d'Zd( Zd9d)Zd9d*Zd9d+Z d9d,Z!d9d-Z"d9d.Z#d9d/Z$d<d1Z%d9d2Z&d9d3Z'dS )=uw  Per-provider model-selection wizard flows for ``hermes setup`` / ``hermes model``.

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

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

main.py-internal helpers the flows call (``_prompt_api_key``, ``_save_custom_provider``,
the reasoning-effort/stepfun/qwen helpers, ``_run_anthropic_oauth_flow``, …) are
imported lazily inside the flows (``from hermes_cli.main import ...`` resolves at
call time, when main.py is fully loaded) so this module never imports
``hermes_cli.main`` at import time -> no import cycle.
    )annotationsN) clear_model_endpoint_credentials)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       B/home/thesage/.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>D   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.authr0   )r-   pconfigr0   s      r    _existing_api_key_for_model_flowr3   P   s'    @@@@@@++KAAAr   r   provider_namebase_urlr5   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_poolNr4   Fsourcemodel_configTid)removed_ids)agent.credential_poolr9   r:   r1   r;   r<   
isinstancedictitemsr   r   listgetappend	Exception)r6   r5   r9   r:   r;   r<   active_pool_keypoolspool_keyentriesretainedr@   changedentryentry_ids                  r   /_prune_replaced_custom_model_config_credentialsrQ   W   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2rX   3rY   rW   )	hermes_cli.setuprV   printrH   	enumerateinputstripKeyboardInterruptEOFError)rR   choicesrV   idxilabelmarkerchoices           r   _prompt_auth_credentials_choicerp      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providerr6   chat_completionsapi_modeFclear_api_modeDefault model set to: z (via OpenRouter)
No change.)hermes_cli.mainrs   hermes_constantsrt   r1   ru   rv   rw   rx   r3   rd   hermes_cli.modelsr   r   hermes_cli.configr   r   rF   rB   rC   r   )configr   rs   rt   ru   rv   rw   rx   r2   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~   presetrC   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_modelsrZ   start    r^   r   :r   
aggregatorz  Aggregator:  N)rd   re   rF   )r~   r   rk   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_URLrr   PROVIDER_REGISTRYrv   rw   rx   )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   r6   r   r   r   z (via Vercel AI Gateway)r   )r   r   r   rs   r1   r   rv   rw   rx   r   r   rd   r   r   r   r   r   rF   rB   rC   )r   r   r   rs   r   rv   rw   rx   r   r2   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   rw   rx   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)rU   z"Select a Mixture of Agents preset:rZ   r[   r\   r]   r^   z  Choice [1-]: r   r   Tr   r6   r   z (via Mixture of Agents)) r1   rw   rx   r   r   r   hermes_cli.moa_configr   rB   rC   rF   rd   rE   keyslenrG   indexrc   rV   rH   re   rf   rg   rh   ri   maxminint
ValueErrorr   popr   )r   r   rw   rx   r   r   r   r   r   namesdefault_namerowsnr   	agg_label	ref_countsuffixdefault_idxrV   rk   rl   rowrn   rawselected_namer   r   r   s                               r   _model_flow_moar   9  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_staterv   rw   _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.r6   r{   )r   r   unavailable_modelsr   unavailable_messager   r   r   r   r   r   OPENAI_BASE_URLOPENAI_API_KEYr   z (via Nous Portal)r   )-r1   r   rv   rw   r   r   r   r   r   r   r   r   r   r   r   hermes_cli.nous_subscriptionr   rF   rd   argparse	Namespacegetattrr   rH   
SystemExitr   r   r   r   r   r   r   rB   relogin_requiredr   hermes_cli.nous_accountr   r   r   rstripr   rC   rg   r   r   )0r   r   argsr   rv   rw   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_statusrv   rw   r   _login_openai_codexr   DEFAULT_CODEX_BASE_URL)get_codex_model_ids	logged_inu     OpenAI Codex credentials: ✓zOpenAI Codex credentials:rX   z&Starting a fresh OpenAI Codex login...zopenai-codexTforce_new_loginr   Nr   zLogin failed.rY   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   )r1   r  rv   rw   r   r  r   r  hermes_cli.codex_modelsr  rF   rd   rp   r   r   r  rH   r  )r   r   r  rv   rw   r   r  r   r  r  statusro   r  r
  _codex_token_codex_statusr  _codex_credscodex_modelsr   s                       r   _model_flow_openai_codexr'  o  s                     <;;;;;""$$Fzz+ &/00001LMMX:;;;GGG$.00	##%n5$(    
    2333   ,s,,--- +*,,F::k** o&&& xF   	?@@@	 *,,I	+<^+LMMMM 	 	 	.///FF 	 	 	(3(()))FFFFF	 L--//[)) 	8(,,Y77L    	IIIIII<<>>L'++I66LL 	 	 	D	 '&LAAAL&&#'/$*  H  8$$$##N4JKKKDxDDDEEEEEls`   'B0 0C2	C2C--C2%E3 3F5	F5F00F5;4G0 0
G=<G=%H) )
H65H6)r  c          	        ddl m}m}m}m}m}m}m}	m}
 ddl	m
}  |            }|                    d          rt          d           t                       t          d          }|dk    rt          d           t                       	 t          j        t!          t#          |d	d
                    t#          |dd                    } |||
d         d           n# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY w|dk    rdS nt          d           t                       	 t          j        t!          t#          |d	d
                    t#          |dd                    } |||
d                    nE# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY w|	}	  |            }|                    d          pd                                                    d          p|}n# t&          $ r Y nw xY wt-          |                    d          p|                    d          pg           } |||p|r|d         nd          }|r, ||            |d|           t          d| d           dS t          d           dS )zRxAI Grok OAuth (SuperGrok / Premium+) provider: ensure logged in, then pick model.r   )get_xai_oauth_auth_statusrv   rw   r   %resolve_xai_oauth_runtime_credentials_login_xai_oauthDEFAULT_XAI_OAUTH_BASE_URLr   _PROVIDER_MODELSr  u8     xAI Grok OAuth (SuperGrok / Premium+) credentials: ✓z2xAI Grok OAuth (SuperGrok / Premium+) credentials:rX   z#Starting a fresh xAI OAuth login...r   Fr   N)r   r   z	xai-oauthTr  r   r   rY   zHNot logged into xAI Grok OAuth (SuperGrok / Premium+). Starting login...r6   r   r   xaizgrok-build-0.1)r   r   u.    (via xAI Grok OAuth — SuperGrok / Premium+)r   )r1   r)  rv   rw   r   r*  r+  r,  r   r   r.  rF   rd   rp   r   r   r   r  r  rH   rg   r  rE   )_configr   r  r)  rv   rw   r   r*  r+  r,  r   r.  r"  ro   r  r
  r6   r  modelsr   s                       r   _model_flow_xai_oauthr2    s   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 322222&&((Fzz+ *HIII0@
 
 X7888GGG$.#GD,$F$FGG#D)T::  	 ! %k2$(    
    2333   ,s,,--- xF   	XYYY	 *lE B BCCi66  I Y(9+(FGGGG 	 	 	.///FF 	 	 	(3(()))FFFFF	 *H5577IIj))/R6688??DDP    "&&{33X7G7K7KE7R7RXVXYYF&&v]=y\bOxvVWyyhxzzzH 8$$$##K:::_x___`````lsQ   
AC! !D#=	D#DD#AF! !G#=	G#GG#)AH2 2
H?>H?c                   ddl m} ddlm}m}m}m}m}m} ddl	m
}	  |            }
|
                    d          st          d           t          d           |
                    d          }|rt          d	|            |
                    d
          r%t          d|
                    d
                      dS d}	  |d          } |	|d         |d                   }n# t          $ r Y nw xY w|st          |          }|p|r|d         nd} |||d|          }|r, ||            |d|           t          d| d           dS t          d           dS )zAQwen OAuth provider: reuse local Qwen CLI login, then pick model.r   )_DEFAULT_QWEN_PORTAL_MODELS)get_qwen_auth_status resolve_qwen_runtime_credentialsrv   rw   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{   r6   zqwen3-coder-plusz
qwen-oauthr   r   r   r   z (via Qwen OAuth)r   )r   r4  r1   r5  r6  rv   rw   r   r7  r   r9  rF   rd   rH   rE   )r0  r   r4  r5  r6  rv   rw   r   r7  r9  r"  r:  r1  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   rv   rw   r   )resolve_minimax_oauth_runtime_credentialsr   r   _login_minimax_oauthr   zminimax-oauthr   z0Not logged into MiniMax. Starting OAuth login...regionNglobalr   Fr   r   )rB  r   r   r   r   r-  r6   )r   r   u   ✓ Using MiniMax model: )r1   r   rv   rw   r   r@  r   r   rA  r   rF   rd   r   r   r  r   r  rH   r   r.  )r   r   r  r   rv   rw   r   r@  r   r   rA  r   r  r  r
  r  r.  r   r   s                      r   _model_flow_minimax_oauthrD  H  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           	 t!          d                                                                           }n# t$          t&          f$ r d!}Y nw xY w|d"v r.|                    d          dz   }|r|}t          d#|            t                       dd$lm}  |||          }|                    d%          r;|                    d&          r&t          d'|d&          d(           |d&         }|r|}n|                    d)          Lt          d*|                    d+           d,t9          |                    d)          pg            d-           n}t          d.|                    d+           d/           |                    d0          rB|d0         }|                    d          rt          d1|            nt          d2|            |                     d3          }d}t;          |t<                    r6t?          |                    d4          pd                                          } |||5          }|rt          d6|            nt          d7           d}|                    d)          pg }	 t9          |          d8k    r{t          d9|d                     t!          d:                                                                          }|d"v r
|d         }nt!          d;                                          }nt9          |          d8k    rt          d<           tA          |d8          D ]\  }}t          d=| d>|            t!          d?t9          |           d@                                          }|!                                rCd8tE          |          cxk    rt9          |          k    rn n|tE          |          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	 tE          | #                    dCd          #                    dDdE          #                    dFdE                    }#|#dk    rd}#n%# tH          $ r t          dG|  dH           d}#Y nw xY wd}$|rdtJ          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           tW          ||"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.r1  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-detectrZ   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   r6   z${}r{   r    (via )zFEndpoint saved. Use `/model` in chat or `hermes model` to set a model.)context_lengthr~   r   key_envr4   ),r   rF  rG  rH  r1   rw   rx   r   rI  r   r   r   r   hermes_cli.secret_promptrK  rd   rf   rg   rh   ri   r   r  r   anyendswithr   r\  rF   r   rB   rC   r   re   isdigitr   replacer   urllibparseurlparsehostnameportr   rQ   )+r   rF  rG  rH  rw   rx   rI  r   r   r   r   rK  current_urlcurrent_keyr6   r{   effective_urleffective_key_looks_local_add_v1r\  probe	suggestedr  rb  r   
model_namedetected_modelsconfirmrl   mpickcontext_length_strr   display_namerl  custom_key_env_parsed	_identityr   r   _caller_modelrX  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/

"#KLLRRTT

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

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

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

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

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

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

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

    Context lengths for the chosen model are resolved via the standard
    :func:`agent.model_metadata.get_model_context_length` chain
    (models.dev, provider metadata, hardcoded family fallbacks).
    r   r   r   r   r   r   )azure_detectr   r   zazure-foundryr6   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 (NrL  z...)zhe.g. https://<resource>.openai.azure.com/openai/v1 or https://<resource>.services.ai.azure.com/anthropiczAPI endpoint URL [r   rP  r   z$No endpoint URL provided. Cancelled.rQ  rS  rT  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.ra   r`   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=rk  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]: )rZ  r[  
Cancelled.)r   u0   ⚠ Could not build token provider for probing: rJ  rN  rM  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:   rZ   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   rl  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: rc  z tokenszA    Context length: not auto-detected (will fall back at runtime))-r1   rw   rx   r   r   r   r   r   
hermes_clir  rF   rB   rC   r   rg   r   rd   rf   rh   ri   r  r   agent.azure_identity_adapterr  r  r  r  r  ImportErrorjoinrH   rn  rK  detectrE   r1  r   reasonr   re   rq  r   r   lookup_context_lengthr   )>r   r   rw   rx   r   r   r   r   r  r  current_base_urlrb  current_auth_mode
_cur_entracurrent_entracurrent_api_key_lbl_placeholderr6   rz  _auth_defaultauth_choice	use_entraauth_mode_labelr{  entra_overridesr  entra_scoper  r  r  r  r  r
  _persisted_scope_overrider0  infor  tagerrr  ansrK  r{   	detectiondiscovered_modelsr   
mode_labeldefault_choicemode_choiceeffective_modelrl   r&   r  r  ctx_lenr   r   clean_entrakeyval
auth_labels>                                                                 r   _model_flow_azure_foundryr  q  s   B HGGGGGGG            (''''' 

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

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

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

    Always probes the endpoint's /models API to let the user pick a model.
    If a model was previously saved, it is pre-selected in the menu.
    Falls back to the saved model if probing fails.
    r   )%_custom_provider_api_key_config_value&_custom_provider_base_url_config_valuerH  r   r   r8  r~   r6   r   r   r{   rm  r   provider_keydiscover_modelsT>   0nofalser1  c                n    g | ]2}t          |                                          #t          |          3S rV  )r   rg   r$   r  s     r   
<listcomp>z,_model_flow_named_custom.<locals>.<listcomp>  s1    JJJ3q66<<>>JSVVJJJr   c                ~    g | ]:}t          |t                    |                                +t          |          ;S rV  )rB   r   rg   r  s     r   r  z,_model_flow_named_custom.<locals>.<listcomp>	  sM     
 
 
*Q*<*<
AB
FF
 
 
r   z  Provider: z  URL:      z  Current:  z2Using configured models (discover_models: false): zFetching available models...r   g       @zFound z model(s):
)curses_radiolistc                *    g | ]}|k    r| d n|S )
 (current)rV  )r$   r  saved_models     r   r  z,_model_flow_named_custom.<locals>.<listcomp>+  s>       @AA$4$41    !  r   rT   zSelect model from r   )r   cancel_returns
searchabler  NrZ   r  r]   r^   z. Cancelz
Choice [1-r   rP  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   rh  	providersdefault_modelapi_key_ref)r   u   
✅ Model set to: z   Provider: r`  rk  )(r   r  r  rH  r1   rw   rx   r   r   r   r   r9  rF   rg   osenvironrB   r   r   rC   rE   rd   r   r   hermes_cli.curses_uir  r  NotImplementedErrorOSError
subprocessSubprocessErrorre   rf   r   r   rh   ri   r   r   r   )(r   provider_infor  r  rH  rw   rx   r   r   r9  r~   r6   r   r{   rm  r  config_api_keydiscoverconfigured_models
cfg_modelsr1  fetch_kwargsr   r  
menu_itemsrk   r  rl   r  r   r  r   r   custom_api_modeproviders_cfgprovider_entryoriginal_api_key_reforiginal_api_keyhad_inline_api_keyr  s(                                          @r   _model_flow_named_customr    s	    E  E  E  E  E  E  E  E  E  EGGGGGGGG::::::::222222 DZ(H  R00H	2..G	2..G##GR00K!%%n55;BBDDL  .w .*.."--::='RRN   !2D99H(C   @>>##+??#%""8R00J*d## 
JJZJJJ	J	%	% 

 
&
 
 
 

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

 18<   n%%% 
	& 
 5666	>k>>>??EEGGV;JJ!8, 	 	 	.!!!FF	 	PQQQ	~..4466JJ!8, 	 	 	.!!!FF	  	2333F z"""
+--CGGGEeT"" &+3E""G 
.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	
-
-
-...	
-$
-
-(
-
-
-.....so   A"K :K BPAO:OOP&P
P	P

PP%'Q  Q10Q1!R& & S
	S
c                   ddl m}m}m} ddlm}m}m}m}m	}	 ddl
m}
m}m} ddlm}m}m}m}m}m} d}||         } |	|          }|                    dd          }|                    d	d          }|st-          d
           t-                       t-          d           t-          d           t-          d           t-          d           t-          d           t-                       t-          d           t-          d           t-          d           t-          d           t-                       	 t/          d                                          }n&# t2          t4          f$ r t-                       Y dS w xY w|dk    rz	 ddlm}  |            }|r* |
d|           t-          d           t-                       nt-          d           dS n# t:          $ r}t-          d|            Y d}~dS d}~ww xY w|dk    rddlm} 	  |d                                          }n&# t2          t4          f$ r t-                       Y dS w xY w|st-          d           dS 	 dd lm }  ||          \  }} |st-          d!|             dS n# tB          $ r Y nw xY w |
d|           t-          d"           t-                       nt-          d           dS  |	|          }|                    dd          }|                    d	d          }ni|d#v r2dd$l"m#}!  |!|          }"t-          d%|dd&          d'| |" d(           n%|d)k    rt-          d*           nt-          d+           t-                       |j$        }# ||          }$|$rd, |$D             n |||#          }% |||$|-          p|}&|%r-d. |%D             }'t-          d/tK          |'           d0           n6|                    |g           }'|'rt-          d1           t-          d2           |'r ||'|&||#|3          }(n<	 t/          d4                                          }(n# t2          t4          f$ r d}(Y nw xY w|(r@ ||(|$|-          p|(}( |            }) ||)          }* ||(|$|-          }+d},|+r t-          d5|( d6            ||+|*7          }, ||(            |            }-|-                    d8          }.tM          |.tN                    s|.rd9|.ini }.|.|-d8<   ||.d:<   |#|.d;<    ||(|$|-          |.d<<   tQ          |.d=>           |, ||-|,            ||-            |             t-          d?|( d@|j)         d(           |+r-|,dAk    rt-          dB           dS |,rt-          dC|,            dS dS dS t-          dD           dS )EzAGitHub Copilot flow using env vars, gh CLI, or OAuth device code.r   )_current_reasoning_effort"_prompt_reasoning_effort_selection_set_reasoning_effort)r   rv   rw   rx   $resolve_api_key_provider_credentials)r   r   r   )r.  r9  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]: Nr`   )copilot_device_code_loginCOPILOT_GITHUB_TOKENz  Copilot token saved.z  Login cancelled or failed.z  Login failed: ra   rJ  z   Token (COPILOT_GITHUB_TOKEN):   Cancelled.)validate_copilot_tokenu     ✗ z  Token saved.>   GH_TOKENGITHUB_TOKENformat_secret_source_suffixz  GitHub token: rL  u	   ... ✓ (rk  zgh auth tokenu*     GitHub token: ✓ (from `gh auth token`)u     GitHub token: ✓c                d    g | ]-}|                     d           |                     d d          .S r?   r   rF   r$   items     r   r  z'_model_flow_copilot.<locals>.<listcomp>  s5    BBB488D>>B$		BBBr   catalogr{   c                    g | ]}||S rV  rV  )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   r6   r   Fr   r   rj  nonez"Reasoning disabled for this model.zReasoning effort set to: r   )*r   r  r  r  r1   r   rv   rw   rx   r  r   r   r   r   r   r.  r9  r  r  r  r  rF   rd   rf   rg   rh   ri   hermes_cli.copilot_authr  rH   rn  rK  r   r  hermes_cli.env_loaderr  inference_base_urlr   rB   rC   r   r~   )/r   r   r  r  r  r   rv   rw   rx   r  r   r   r   r.  r9  r  r  r  r  r-   r2   r  r{   r=   ro   r  tokenr
  rK  new_keyr   validr  r  	bw_suffixeffective_baser  live_modelsnormalized_current_model
model_listr   initial_cfgr  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(+#
 
 
	^,,2244HH!8, 	 	 	HHH	  2&&   
  	 "kmm22;??::
 
 

  	>x>>>???@@!.  O 	8$$$kmm  %&& 	!*/7Y&&RE CL'j*j22
 
 
j
 	)uEEEE&!!#777CFxFFw|FFFGGG 	E&((:;;;;;  EC/CCDDDDD		E 	EE E 	lsa   8!E E=<E=AG 
G= G88G=H+ +II%(J 
JJ1!Q Q)(Q)c                   ddl m}m}m}m}m}m}m} ddlm	}	m
}
m} ddlm}m} ~ d}||         } ||          }|                    d          p|                    d          pd}|                    d	          p|j        }t#          d
           t#          d           t#          d           t#          d|            t#          d|            t#                       	  ||          }n9# t$          $ r,}t#          d|            t#          d           Y d}~dS d}~ww xY w|                    d	          p|}d}	  |d          }|                    dd          }n# t$          $ r Y nw xY w |
|          } ||||          p|}|r-d |D             }t#          dt'          |           d           n6|	                    dg           }|rt#          d           t#          d           |r ||||||          }n<	 t)          d                                          }n# t,          t.          f$ r d}Y nw xY w|st#          d           dS  ||||          p|} ||            |            }|                    d          }t1          |t2                    s|rd|ini }||d<   ||d<   ||d	<   d |d!<   t5          |d"#            ||            |             t#          d$| d%|j         d&           dS )'z4GitHub Copilot ACP flow using the local Copilot CLI.r   )r   rv   rw   rx   $get_external_process_provider_statusr  -resolve_external_process_provider_credentials)r.  r  r  r   zcopilot-acpresolved_commandcommandr  r6   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  r  r   r  r   r   r   r   r   r   Fr   r   rj  rk  )r1   r   rv   rw   rx   r#  r  r$  r   r.  r  r  r   r   r   rF   r  rd   rH   r   rf   rg   rh   ri   rB   rC   r   r~   )r   r   r   rv   rw   rx   r#  r  r$  r.  r  r  r   r   r-   r2   r"  r%  r  r  r
  catalog_api_keycatalog_credsr  r  r  r   r   r   s                                r   _model_flow_copilot_acpr*  h  s                             
 ;:::::::K,G11+>>F

%&&L&**Y*?*?L9  ZZ
++Iw/IN	
KLLL	
NOOO	
TUUU	
*(
*
*+++	
/~
/
/000	GGG==kJJ   nsnni	
 	
 	
 	 YYz**<nNO<<YGG'++Ir::    )(99G""#	
 	
 	
 	
    	UOOWOOO
GZGGGHHHH%)))R88
 	U^   STTT **2(++
 
 
	^,,2244HH!8, 	 	 	HHH	  l 	#"#	
 	
 	
 	
   x   
+--CGGGEeT"" &+3E""G#E*&E**E*$U5AAAAK	
B8
B
B7<
B
B
BCCCCCs<   #C/ /
D%9!D  D%!E$ $
E10E1!H* *I ?I c                   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   rr   )r   KIMI_CODE_BASE_URLrv   rw   rx   r  r-  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   r6   r   Fr   zKimi CodingMoonshotr   rj  rk  r   )r   rs   r1   r   r,  rv   rw   rx   r   r   r   r   r   r   r.  base_url_env_varr3   r   rd   r  rF   rf   rg   rh   ri   rB   rC   r   r   )r   r   rs   r   r,  rv   rw   rx   r   r   r   r   r.  r-   r2   base_url_envr   r   r   is_coding_planr  r  r   r   r   endpoint_labels                             r   _model_flow_kimir3    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 **'(+(
 
 
	12288::HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j		*d###(uEEEEC*8HjHxHH~HHHIIIIIls   =!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_regionrs   _prompt_provider_choice_stepfun_base_url_for_regionr   r  )r.  r9  stepfunr   r   Nr   r6   internationalzInternational (rk  chinazChina (u     ← currently active)rY   rT   c                    g | ]\  }}|S rV  rV  )r$   rg  rm   s      r   r  z'_model_flow_stepfun.<locals>.<listcomp>p  s    )P)P)PHAu%)P)P)Pr   rY   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   rj  )&r   r5  rs   r6  r7  r1   r   rv   rw   rx   r   r   r   r   r   r   r.  r9  r/  r3   r  getenvrF   rB   rC   r   rg   r  insertrG   rd   r   r~   rf   rh   ri   r   r   )%r   r   r5  rs   r6  r7  r   rv   rw   rx   r   r   r   r   r.  r9  r-   r2   r0  r   r   r   current_baser  current_regionregion_choicesordered_regions
region_keyrm   
region_idxselected_regionr  r  r  r   r   r   s%                                        r   _model_flow_stepfunrG  8  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  
  **'(+(
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL'j*j		*d###(uEEEECu++wFxFFw|FFFGGGGGls   !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|r ||            |            }|                    d          }t/          |t0                    s|rd|ini }||d<   d|d<   |
|d<   |                    d d           t5          |d!"           |                    di           }t/          |t0                    si }||d#<   ||d<    |d$|            |d%|
            ||            |             t          d&| d'| d(           t          d|
            dS t          d)           dS )*u   Bedrock API Key mode — uses the OpenAI-compatible bedrock-mantle endpoint.

    For developers who don't have an AWS account but received a Bedrock API Key
    from their AWS admin. Works like any OpenAI-compatible endpoint.
    r   rv   rw   rx   )r   r   r   r-  zhttps://bedrock-mantle.z.api.aws/v1)r0   ru   bedrockBedrockr{   )AWS_BEARER_TOKEN_BEDROCKr}   r  rL  z  Bedrock API Key: N      ... ✓z  Endpoint: rJ  r       ✓ API key saved.
  Showing z curated modelsrh  r     Model ID: r   r   r   r6   r   Fr   rB  r   r     Default model set to: z (via Bedrock API Key, rk    No change.)r1   rv   rw   rx   r   r   r   r   r   r.  r0   ru   r  r  rd   rn  rK  rg   rh   ri   rF   r   rf   rB   rC   r   r   )r   rB  r   rv   rw   rx   r   r   r   r.  mantle_base_urlr0   ru   bedrock_pconfigr   r   r  source_suffixrK  r{   r  r   r   r   bedrock_cfgs                            r   _model_flow_bedrock_api_keyrX    sI            
         
 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 **'%,(
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL$j+j		*d###(uEEEE ggi,,+t,, 	K &H$I 	'666(/:::CSSS&SSSTTT._../////ns$   !B? ?C"!C"-!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|                    |           it0          dz   t3                      }|D ]R}|d         "t5          "fd D             d          }|r*|                    "t9          |          d                    Sg }|D ]9}|d         ""                              s"|v r$|                    |           :g d! d@fd%! !fd&}|                    |'           d( |D             }t          d)t9          |           d*t9          |           d+           nJ|                    d,g           }|r!t          d-t9          |           d.           nt          d/           dS |r |||d,d0| d12          }n<	 t!          d3                                          }n# t$          t&          f$ r d}Y nw xY w|r ||            |            }|                    d4          }tA          |tB                    s|rd5|ini }||d4<   d,|d6<   d0| d1|d7<   |"                    d8d           tG          |d9:           |                    d,i           }tA          |tB                    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   rI  r   r-  )has_aws_credentialsresolve_aws_auth_env_varresolve_bedrock_regiondiscover_bedrock_modelsu.     ✗ boto3 is not installed. Install it with:z    pip install boto3Nu<     ⚠ No AWS credentials detected via environment variables.zE  Bedrock will use boto3's default credential chain (IMDS, SSO, etc.)z  AWS credentials: u    ✓z<  AWS credentials: boto3 default chain (instance role / SSO)z  AWS Region [r     Choose authentication method:z)    1. IAM credential chain (recommended)zB       Works with EC2 instance roles, SSO, env vars, aws configurez    2. Bedrock API Keyu<          Enter your Bedrock API Key directly — also supportsz5       team scenarios where an admin distributes keysz  Choice [1]: ra   z  Discovering models in rM  )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>l	  s/      @@3>>!$$@@@@@@r   c              3  D   K   | ]}|                                 v V  d S r!   r   )r$   sr&   s     r   r'   z&_model_flow_bedrock.<locals>.<genexpr>n	  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>z	  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>	  rf  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(   rZ      )re   r   )r  r&   baserl   rec_RECOMMENDED_BASESrk  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?   rV  r  s     r   r  z'_model_flow_bedrock.<locals>.<listcomp>	  s    ///!ag///r   r  z text model(s) (filtered from z total)rJ  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=  rQ  r   r   r   r6   r   Fr   rB  rR  z (via AWS Bedrock, rk  rS  )r&   r   r   r   )$r1   rv   rw   rx   r   r   r   r   r.  agent.bedrock_adapterrZ  r[  r\  r]  r  rd   rf   rg   rh   ri   rX  ro  r,   rG   r*   setr)   addr   r   sortrF   rB   rC   r   r   )#r   r   rv   rw   rx   r   r   r.  rZ  r[  r\  r]  auth_varrA  region_inputrB  r  r  _EXCLUDE_PREFIXES_EXCLUDE_SUBSTRINGSfilteredr  profile_base_idsri  dedupedrq  r  r   r   r   rW  rj  rp  rk  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AnAAABBHHJJx(    +^F 

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

0V
0
0
0111))&11K 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	
 
 
	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL%jMvMMMj		*d###(uEEEEggi,,+t,, 	K &H$ICOOOfOOOPPPPPnsE   + 6A%$A%&%D D/.D/-!G 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   rI  )r   r   r   r-  VERTEX_CREDENTIALS_PATHGOOGLE_APPLICATION_CREDENTIALSr   z,  Vertex credentials: service account JSON (u   ) ✓z;  Vertex credentials: Application Default Credentials (ADC)z5    Vertex uses OAuth2, not a static API key. Either:u9         • run 'gcloud auth application-default login', oruQ         • set VERTEX_CREDENTIALS_PATH in ~/.hermes/.env to a service account JSONvertex
project_idz  GCP project ID [zfrom credentialsr   NrB  rC  z  Vertex region [zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-previewzGhttps://aiplatform.googleapis.com/v1beta1/projects/<project>/locations/z/endpoints/openapirR  z@-aiplatform.googleapis.com/v1beta1/projects/<project>/locations/r=  r   r   r   r6   r   Fr   rR  z (via Google Vertex AI, rk  rS  )r1   rv   rw   rx   r   r   r   r   r   r.  rg   rd   rF   rB   rC   r   rf   rh   ri   r   r   )r   r   rv   rw   rx   r   r   r   r.  sa_pathr   
vertex_cfgcurrent_projectproject_inputr  rA  rx  rB  r  base_url_previewr   r   vcfgs                          r   _model_flow_vertexr  	  s`            
 JIIIIIIIII222222 	/00 	=9::	egg	 
  cKWKKKLLLLKLLLEFFFIJJJabbb	GGG
+--C""Jj$'' 
 *..66<"==CCEEOK!F4FKKK
 

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

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

    Returns the selected base URL.  Falls back to *current_base* on cancel
    or error.
    r   )r6  )ZAI_ENDPOINTSc                     g | ]\  }}}}||fS rV  rV  )r$   rg  urlrm   s       r   r  z(_select_zai_endpoint.<locals>.<listcomp>V
  s%    BBB 035s|BBBr   r   r   c                $    g | ]\  }}| d | dS )r`  rk  rV  )r$   rm   r  s      r   r  z(_select_zai_endpoint.<locals>.<listcomp>e
  s-    <<<jeS%!!3!!!<<<r   zCustom proxy URLzSelect Z.AI / GLM endpoint:)r   rR   NzCustom base URL [r   rQ  M     Invalid URL — must start with http:// or https://. Keeping current value.rZ   )r   r6  r1   r  rg   r  re   r   rG   rf   rh   ri   rd   r   )r@  r6  r  optionsnormalized_currentr   rk   rg  r  rj   r   overrides               r   _select_zai_endpointr  G
  s    877777------ CBMBBBG&,"3355<<SAA K"7++ ' 'XaC00KE 1  	'g,,K<<G<<<GNN%&&&&&+  H
 3w<<	 BBBBCCIIKKHH!8, 	  	  	 GGG	   	 ""#:;; 	 abbbs###8Q&&s+++s   %C7 7!DDc                  / ddl m} ddlm}m}m}m} ddlm}m	}	m
}
m} ddlm}m}m}m/ |         }|j        r|j        d         nd}|j        pd}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d.lm} |p|r ||          nd}|                    g           }# |||          }$|$r,|$} t/          d&tM          |            d/|j(         d0           n~g }%	 dd1l)m*}&  |&          }%n# t,          $ r Y nw xY w|%rd2 |%D             }'tW          |%          } |#D ]T}(|(                                |'vr<| ,                    |(           |'-                    |(                                           Ut/          d&tM          |            d3           n|#} | r t/          d4tM          |            d5           n|                    g           }#g }%	 dd1l)m*}&  |&          }%n# t,          $ r Y nw xY w|%r|#rud6 |%D             }'tW          |%          })|#D ]T}(|(                                |'vr<|),                    |(           |'-                    |(                                           U|)} n|%} t/          d&tM          |            d3           n|#r6tM          |#          d7k    r#|#} t/          d4tM          |            d5           n|p|r ||          nd} |||          }$|$rKtM          |$          tM          |#          k    r+|$} t/          d&tM          |            d/|j(         d0           n$|#} | r t/          d4tM          |            d5           d8v rL/fd9| 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Ӊd8v r /|,          }, ||,            |
            }-|-                    d          }.tc          |.t\                    s|.rd>|.ini }.|.|-d<   |.d<   ||.d<   te          |.d?@           d8v r ||,          |.dA<   n|.3                    dAd            ||-            |             t/          dB|, dC|j(         dD           dS t/          dE           dS )FzCGeneric flow for API-key providers (z.ai, MiniMax, OpenCode, etc.).r   rr   r   r  )r.  r9  opencode_model_api_modenormalize_opencode_model_idr   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   r6   zaiz
Base URL [r   rQ  r  lmstudio)r   )fetch_lmstudio_models)r{   r6   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{   r6   r   z model(s) from Ollama Cloudnovitar8  r<  r=  )list_agentic_modelsc                6    h | ]}|                                 S rV  rc  r  s     r   	<setcomp>z/_model_flow_api_key_provider.<locals>.<setcomp>A       777a		777r   z" model(s) from models.dev registryrP  r   c                6    h | ]}|                                 S rV  rc  r  s     r   r  z/_model_flow_api_key_provider.<locals>.<setcomp>^  r  r   rL  >   opencode-goopencode-zenc                (    g | ]} |          S rV  rV  )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!   rV  )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   rj  rk  r   )4r   rs   r1   r   rv   rw   rx   r   r   r   r   r   r   r.  r9  r  r  r   r/  r3   agent.gemini_native_adapterr  rH   rd   r  r>  r  rF   r   rg   r   r  rf   rh   ri   r   r   r  r   r  r~   agent.models_devr  rE   rG   ru  rC   fromkeysr   rB   r   r   )0r   r-   r   rs   r   rv   rw   rx   r   r   r   r   r.  r9  r  r2   rm  r0  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  
  s   //////                                   ,G-4-EMg&q))2G+1rL %E[RY$Z$Z!L/)/'	  L%   h<	%EEEEEEE 	% 	% 	% $	%(12220<D|,,," .9\/R44.- 
 %$\:>>Dv~~B   ;   2   ,---:   9   <   BCCCv~~.////
 KLLLGGG L R$}\22Qbib6Q6Q 	""7++1rB266*%%+,,2244::<<KK"266*#5#5#;<<BBDD 	 	 	D	!?W%?Ne
 +>:: 	6;.88\8N<555$	=.===>>DDFFHH!8, 	 	 	GGGHHH	  	* 	*&&'>?? *c    |X666!) j  ------;;;;;;(Ww-V]]7-C-C-CTV	..)N  JJ  	 	 	<s<<===WXXXJJJJJJ	  	HFS__FFFGGG		&	&??????(Ww-V]]7-C-C-CTV
 /.%#
 
 


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

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

 43KOO$--'I'Iz'I'I'IIIJJ
  	BBBBBB..{;;ArGG 	 	 	GGG	**'(+(
 
 
	^,,2244HH!8, 	 	 	HHH	  99922;IIH8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j(uEEEE999 7 7X N NE*IIj$'''CFxFFw|FFFGGGGGls   B BB>B!J   
J-,J-(%L !L21L2N O##OO7S	 	
SS.W   
WW^ ^*)^* !_" "_87_8c                   ddl m} ddlm}m}m} ddlm}m}m	}m
}	 ddlm}
 ddlm}  |            }d}	 ddlm}m}m}  |            }|r ||          rd	}n# t$          $ r Y nw xY wd}|r ||          r|sd	}t'          |          r| p|}| }|r|rvdd
lm} ddlm} d}|d         j        D ]<}t1          j        |d                                          |k    r ||          }|r n=t7          d|dd          d|            n|rt7          d           t7                       t9          d          }|dk    rd	}n|dk    rdS |rt7                       t7          d           t7                       t7          d           t7          d           t7          d           t7                       	 t;          d                                          }n&# t<          t>          f$ r t7                       Y dS w xY w|dk    r ||          sdS n|dk    rt7                       t7          d           t7                       ddl m!} 	  |d                                          }n&# t<          t>          f$ r t7                       Y dS w xY w|st7          d            dS  |	||!           t7          d"           nt7          d#           dS t7                       |
"                    dg           }|r |||d$          }n<	 t;          d%                                          }n# t<          t>          f$ r d}Y nw xY w|r ||            |            }|"                    d&          }tG          |tH                    s|rd'|ini }||d&<   d|d(<   |%                    d)d           tM          |            ||            |             t7          d*| d+           dS t7          d,           dS )-uR   Flow for Anthropic provider — OAuth subscription, API key, or Claude Code creds.r   )_run_anthropic_oauth_flowrI  )r   r   r   save_anthropic_api_keyr-  )get_anthropic_keyF)read_claude_code_credentialsis_claude_code_token_valid_is_oauth_tokenTr  )r   r   	anthropicz  Anthropic credentials: NrM  rN  u.     Claude Code credentials: ✓ (auto-detected)zAnthropic credentials:rX   rY   r^  z0    1. Claude Pro/Max subscription (OAuth login)z(    2. Anthropic API key (pay-per-token)r  r_   r`   ra   z>  Get an API key at: https://platform.claude.com/settings/keysrJ  z  API key (sk-ant-...): r  )save_fnrO  rS  )r   r   z-Model name (e.g., claude-sonnet-4-20250514): r   r   r   r6   r   z (via Anthropic)r   )'r   r  r1   rv   rw   rx   r   r   r   r   r  r   r.  r  agent.anthropic_adapterr  r  r  rH   r   r  r  r   r   r  r>  rg   rd   rp   rf   rh   ri   rn  rK  rF   rB   rC   r   r   ) r   r   r  rv   rw   rx   r   r   r   r  r.  r  r   cc_availabler  r  r  cc_credsexisting_is_stale_oauth	has_creds
needs_authr  r   rV  varro   rK  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 
**'(
 
 
	LMMSSUUHH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j		*d###(///CAxAAABBBBBlsG   #A 
A'&A'7!G G<;G<I) )JJ!L( (L>=L>)r   r   r   r   )r   r   r   r   r   r   )r-   r   r   r.   )r6   r   r5   r   r   r7   )rR   r   r   r   )r   )r~   r   r   rC   r   r7   )r   N)r@  r   r   r   )(__doc__
__future__r   r   r  r  urllib.parsers  r   r   hermes_cli.providersr   r*   r   r,   r3   rQ   rp   r   r   r   r   r  r'  r2  r>  rD  r  r  r  r!  r*  r3  rG  rX  r~  r  r  r  r  rV  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`~/ ~/ ~/@E E E ENsD sD sD sDjY Y Y Yvn n n n`h h h hTK K K K\e e e eN7, 7, 7, 7,tw w w wr	U U U U U Ur   