
    `gj%                      d Z ddlmZ ddlZddlZddlZddlmZ dZd"dZ	d#dZ
dd		 	 	 	 	 d$d
Zd%dZd&dZd'dZd&dZd(dZd&dZd&dddZd&dZd(dZd Zd&dZd Zd&dZd&dZd&dZd&dZd&dZd&dZd&dZd)dZd&d Z d&d!Z!y)*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)	us.eu.ap.apac.jp.ca.sa.me.af.c                j    | xs dj                         }dD ]  \  }}|j                  |      s|c S  y)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)region_namergeoregion_prefixess       O/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/model_setup_flows.pybedrock_region_geo_prefixr   )   sC    		!!#A! 
_ <<(J
     c                    | xs dj                         t        fdt        D        d      }|j                  d      ryt	        |      }|sy|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   | ]  }j                  |      s|  y wNr   .0pmids     r   	<genexpr>z5bedrock_model_routable_from_region.<locals>.<genexpr>B   s     Ma3>>!;LM   !!Nglobal.Tr   )r   r   r	   )r   nextBEDROCK_GEO_PREFIXESr   r   )model_idr   matched_geor   r!   s       @r   "bedrock_model_routable_from_regionr)   :   sl     >r
 
 
"CM#7MtTKcnnY7
#K
0C
e|555#r   r   provider_namec               6   	 ddl m}m} ddlm}m}  || |xs d      }|sy |d      }t        |t              sy|j                         D ]  \  }}	t        |t              r&|j                  |      r||k(  st        |	t              s=g }
g }d}|	D ]g  }t        |t              rD|j                  d      dk(  r0d	}|j                  d
      }|r|j                  t        |             W|
j                  |       i |s |||
|        y# t        $ r Y yw xY w)ab  Drop stale ``model_config`` credentials from inactive custom pools.

    ``model_config`` means "the credential currently stored under
    ``model.api_key``". After an explicit custom-endpoint switch, any old
    custom pool still carrying that source points at the previous endpoint and
    can be selected before the freshly saved config is tried.
    r   )CUSTOM_POOL_PREFIXget_custom_provider_pool_key)read_credential_poolwrite_credential_poolNr*   Fsourcemodel_configTid)removed_ids)agent.credential_poolr-   r.   hermes_cli.authr/   r0   
isinstancedictitemsstrr   listgetappend	Exception)base_urlr+   r-   r.   r/   r0   active_pool_keypoolspool_keyentriesretainedr4   changedentryentry_ids                  r   /_prune_replaced_custom_model_config_credentialsrH   N   s#   &	
 	P6'/4
 $T*%&!& 	SHgx-**+=>.!'40HKG  'eT*uyy/Bn/T"G$yyH#**3x=9&' %hkR)	S*  s"    D D CD >D 	DDc           	     |   g d}	 ddl m}  || |d      }|dk\  rt                d|   S 	 t        |        t	        |d      D ]"  \  }}|dk(  rdnd}t        d| d| d	|        $ t                	 t        d
      j                         }|dk(  ry|dk(  ryy# t        $ r Y xw xY w# t        t        f$ r d}Y /w xY w)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2rN   3rO   rM   )	hermes_cli.setuprL   printr>   	enumerateinputstripKeyboardInterruptEOFError)titlechoicesrL   idxilabelmarkerchoices           r   _prompt_auth_credentials_choicerg      s    G
:#E7A6!8G.s33  
%Lgq) *5q&c6(!A3b()* 
G+,224 }}#   x( s#   #B 2B' 	B$#B$'B;:B;c           	     4   ddl m} ddlm} ddlm}m}m}m} ddl	m
}  |dddd	
      }	 |d      xs d}
|
st        d       t                 ||	|
d      \  }}|ryddlm}m}  |d      } |dd      } ||||d||xs |
      }|r ||       ddl	m}m}  |       }|j#                  d      }t%        |t&              s|rd|ini }||d<   d|d<   ||d<   d|d<   t)        |d        ||        |        t        d| d       yt        d       y) z5OpenRouter provider: ensure API key, then pick model.r   _prompt_api_key)OPENROUTER_BASE_URL)ProviderConfig_prompt_model_selection_save_model_choicedeactivate_provider)get_env_value
openrouter
OpenRouterapi_key)OPENROUTER_API_KEY)r3   name	auth_typeapi_key_env_varsrt   r   z&Get one at: https://openrouter.ai/keysprovider_idN)	model_idsget_pricing_for_providerTforce_refreshcurrent_modelpricingconfirm_providerconfirm_base_urlconfirm_api_keyload_configsave_configmodeldefaultproviderr?   chat_completionsapi_modeFclear_api_modeDefault model set to: z (via OpenRouter)
No change.)hermes_cli.mainrj   hermes_constantsrk   r6   rl   rm   rn   ro   hermes_cli.configrp   rZ   hermes_cli.modelsrz   r{   r   r   r<   r7   r8   r   )configr   rj   rk   rl   rm   rn   ro   rp   pconfigexisting_key	_resolvedabortrz   r{   openrouter_modelsr   selectedr   r   cfgr   s                         r   _model_flow_openrouterr      sA   /4  0 0	G !!56<"L67&w,WIuE!5 '|4HG&#%,!1\H 8$ 	?m %&*/Y&RE CL(j/j.j(uEC&xj0ABClr   c                r   t        d|         t        d       t        |j                  d      xs g d      D ]7  \  }}t        d| d|j                  d       d	|j                  d
              9 |j                  d      xs i }t        d|j                  d       d	|j                  d
              y)zDPrint the full reference-models + aggregator breakdown for a preset.z
  Preset: z  Reference models:reference_modelsrP   start    rT   r   :r   
aggregatorz  Aggregator:  N)rZ   r[   r<   )ru   presetrb   slotaggs        r   _print_moa_presetr      s    	Jtf
	
 vzz*<=C1M H	TSEDHHZ01488G3D2EFGH
**\
"
(bC	OCGGJ/0#'''2B1C
DEr   c           
        ddl m}m} ddlm}m} ddlm}  |t        | t              r| j                  d      ni       }|j                  d      xs i }|st        d       yt        |j                               }	|j                  d	      xs |	d   }
g }|	D ]  }||   j                  d
      xs i }|r%|j                  d       d|j                  d       nd}t        ||   j                  d      xs g       }||
k(  rdnd}|j                  | d| d| d|         |
|	v r|	j!                  |
      nd}	 ddlm}  |d||      }||dk  rt        d       y|	|   }||   } |       }|j                  d      }t        |t              s|rd|ini }||d<   ||d<   d|d<   t;        |d        |j=                  d!d        ||        ||        |        t                t        d"| d#       t?        ||       y# t&        $ r t        d       t)        |d      D ]%  \  }}|dz
  |k(  rdnd}t        d| d| d|        ' 	 t+        dt        |       d      j-                         }n!# t.        t0        f$ r t        d       Y Y yw xY w|s|}nK	 t3        dt5        t        |      dz
  t7        |      dz
              }n# t8        $ r t        d       Y Y yw xY wY w xY w)$u  Mixture of Agents virtual provider: pick a preset, then persist it.

    Unlike the other provider flows there is no credential step — MoA is a
    virtual provider whose presets reference already-configured providers. We
    always show the preset list (even when there is only one) so the user sees
    what they are selecting, then print the full preset breakdown on selection.
    r   rn   ro   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)rK   z"Select a Mixture of Agents preset:rP   rQ   rR   rS   rT   z  Choice [1-]: r   r   Tr   r?   r   z (via Mixture of Agents)) r6   rn   ro   r   r   r   hermes_cli.moa_configr   r7   r8   r<   rZ   r;   keyslenr=   indexrY   rL   r>   r[   r\   r]   r^   r_   maxminint
ValueErrorr   popr   )r   r   rn   ro   r   r   r   r   r   namesdefault_namerowsnr   	agg_label	ref_countsuffixdefault_idxrL   rb   rc   rowre   rawselected_namer   r   r   s                               r   _model_flow_moar      s    H::
Jvt4Lvzz%0RT
UCggi &BGST E77+,8aL D Iqz~~l+1rCFswwz*+1SWWW-=,>?B	
'9:@bA	$%$52qc2i[vhGHI 0<u/D%++l+!K:#$H$P[\( {cAgl#JM]#F
-CGGGEeT"&+E"G$E)E*
 %U4@	IIj$}%	G	"=/1I
JKmV,[  23a( 	,FAs 1u4U#FBvhas"SE*+	,	,s4yk56<<>C!8, 	,	 C!STQC1=> l#s[   <H AK)&I43K)4JK)JK).K
	K)
K"K)!K""K)(K)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|j#                  d      st%        d       t%                	 t'        j(                  t+        |dd	      t+        |d
d	      t+        |dd	      t+        |dd	      t-        t+        |dd            t+        |dd	      xs dt+        |dd	      t-        t+        |dd                  } |
||d          	  |       xs i } ||       y	ddlm}m}m}m}m}m}  |       }|st%        d       y		  |       } |d      }  |d      }!|!s	  |d      }"|"r|"}d}#	  |d      }$|$r|$j#                  d d      }#g }%d}&|!r<	 dd!l#m$}'m%}(  |(d      }) |'|)d"#      xs d}& ||| |#      \  }}  ||| d$      \  }}%n ||| |#      \  }} |s|%st%        d%       y	|!r>|s<t%        d&       |%r.dd'l m&}* |#xs |*jO                  d(      }+t%        |&xs d)|+ d*       y	t%        d+tQ        |       d,        |||| |%|#|&d|j#                  d-d      |j#                  d.d      /	      },|,r ||,       |j#                  d-d      }- |d|-        |       } | j#                  d0      }.tA        |.tR              rtS        |.      }/n5tA        |.tD              r#|.jU                         rd1|.jU                         i}/ni }/d|/d2<   |,|/d1<   |-r%|-jU                         r|-jO                  d(      |/d-<   n|/jW                  d-d	       tY        |/       |/| d0<    |d3      r |d3d        |d4d        ||        t%        d5|, d6        ||        y	t%        d7       y	# t.        $ r Y y	w xY w# t0        $ r t%        d       Y y	t.        $ r}t%        d|        Y d	}~y	d	}~ww xY w# t.        $ r}tA        ||      xr |jB                  }tA        ||      r |	|      n
tE        |      }|rmt%        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	}~y	t%        d|        Y d	}~y	d	}~ww xY w# t.        $ r Y Ow xY w# t.        $ r Y @w xY w# t.        $ r d}&Y ,w xY w)8z8Nous Portal provider: ensure logged in, then pick model.r   )	get_provider_auth_staterm   rn   _update_config_for_provider resolve_nous_runtime_credentials	AuthErrorformat_auth_error_login_nousPROVIDER_REGISTRY)rp   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.r?   rs   )r   r   unavailable_modelsr   unavailable_messager   r   r   r   r   r   OPENAI_BASE_URLOPENAI_API_KEYr   z (via Nous Portal)r   )-r6   r   rm   rn   r   r   r   r   r   r   r   rp   r   r   r   hermes_cli.nous_subscriptionr   r<   rZ   argparse	Namespacegetattrboolr>   
SystemExitr   r   r{   r   r   r   r   r7   relogin_requiredr:   hermes_cli.nous_accountr   r   r   rstripr   r8   r]   r   r   )0r   r   argsr   rm   rn   r   r   r   r   r   r   rp   r   r   r   r   state	mock_args
_refreshedexcr   r{   r   r   r   r   rz   credsreloginmsg	login_excr   r   refreshed_creds_nous_portal_url_nous_stater   r   r   r   _account_infor   _urlr   r   current_model_cfg	model_cfgs0                                                   r   _model_flow_nousr  L  sY   
 
 
  H#F+E		.1>?	 **"4t<%dOTB!$T:dGT2lE BCi6>$!$T:gdJ>?	I 	#4V#<=(]0b
*:6 	
  +,I<=024 'v.G %6I		>"O ' -f5*/@"E %'	%
 9TJM6!1     Dw 0
	7 )Fw$)
%	% Dw 0
	7 /DE34?$?(?GGLD%T;tf<S)TU	
3y>""_` '#-#/:r2		)R0
H 8$		*b1#FM: "JJw/'../I)3/4E4K4K4M"$5$;$;$=>II &	*'	)]002$1$8$8$=Ij!MM*d+(3#w*+,b1+R0F&xj0BCD"6*lm   	 	./ 	N3%()	4  S),E1E1E(23	(B$C%cU+,;<7$..#"&"$ ""		 I'8'@A 7))5667.se45-J  	 	  :  	%"$	%s   BN 2N ,O R R' :R7 	NN NN O(O0OO	RAR))QR	Q4Q/*R/Q44R<RR	R$#R$'	R43R47SSc                (   ddl m}m}m}m}m}m}m} ddlm	}	  |       }
|
j                  d      rt        d       t                t        d      }|dk(  r\t        d       t                	 t        j                         } |||d	   d
        |       }
|
j                  d      sHt        d       y|dk(  r7yt        d       t                	 t        j                         } |||d	          d}	  |       }|j                  d      r|j                  d      }|s	 ddl m}  |       }|j                  d      } |	|      } |||d	||xs d      }|r! ||        |d	|       t        d| d       yt        d       y# t        $ r t        d       Y yt         $ r}t        d|        Y d}~yd}~ww xY w# t        $ r t        d       Y yt         $ r}t        d|        Y d}~yd}~ww xY w# t         $ r Y w xY w# t         $ r Y w xY w)z9OpenAI Codex provider: ensure logged in, then pick model.r   )get_codex_auth_statusrm   rn   r   _login_openai_codexr   DEFAULT_CODEX_BASE_URL)get_codex_model_ids	logged_inu     OpenAI Codex credentials: ✓zOpenAI Codex credentials:rN   z&Starting a fresh OpenAI Codex login...zopenai-codexTforce_new_loginr   Nr   zLogin failed.rO   z/Not logged into OpenAI Codex. Starting login...rs   )!resolve_codex_runtime_credentials)r   r   r   r   r   r   r   z (via OpenAI Codex)r   )r6   r	  rm   rn   r   r
  r   r  hermes_cli.codex_modelsr  r<   rZ   rg   r   r   r   r>   r  )r   r   r	  rm   rn   r   r
  r   r  r  statusrf   r   r   _codex_token_codex_statusr  _codex_credscodex_modelsr   s                       r   _model_flow_openai_codexr  -  s)      <"$Fzz+/001LMX:;G$..0	#%n5$( +,F::k*o&x?@	 **,I	+<^+LM L-/[)(,,Y7L 	I<>L'++I6L 'LAL&#'/$*H 8$#N4JK&xj0CDEls  23 se,-  	./ 	N3%()	    		s`   ,"F  F= 1)G6 H F:F:"F55F:=G3G3G..G36	HH	HH)r   c          	        ddl m}m}m}m}m}m}m}	m}
 ddl	m
}  |       }|j                  d      rt        d       t                t        d      }|dk(  r[t        d       t                	 t        j                  t!        t#        |d	d
            t#        |dd            } |||
d   d       n^|dk(  rYyt        d       t                	 t        j                  t!        t#        |d	d
            t#        |dd            } |||
d          |	}	  |       }|j                  d      xs dj)                         j+                  d      xs |}t-        |j                  d      xs |j                  d      xs g       } |||xs	 |r|d   nd      }|r! ||        |d|       t        d| d       yt        d       y# t$        $ r t        d       Y yt&        $ r}t        d|        Y d}~yd}~ww xY w# t$        $ r t        d       Y yt&        $ r}t        d|        Y d}~yd}~ww xY w# t&        $ r Y w xY w)zRxAI Grok OAuth (SuperGrok / Premium+) provider: ensure logged in, then pick model.r   )get_xai_oauth_auth_statusrm   rn   r   %resolve_xai_oauth_runtime_credentials_login_xai_oauthDEFAULT_XAI_OAUTH_BASE_URLr   _PROVIDER_MODELSr  u8     xAI Grok OAuth (SuperGrok / Premium+) credentials: ✓z2xAI Grok OAuth (SuperGrok / Premium+) credentials:rN   z#Starting a fresh xAI OAuth login...r   Fr   N)r   r   z	xai-oauthTr  r   r   rO   zHNot logged into xAI Grok OAuth (SuperGrok / Premium+). Starting login...r?   r   r   xaizgrok-build-0.1)r   r   u.    (via xAI Grok OAuth — SuperGrok / Premium+)r   )r6   r  rm   rn   r   r  r  r  r   r   r  r<   rZ   rg   r   r   r   r   r   r>   r]   r   r;   )_configr   r   r  rm   rn   r   r  r  r  r   r  r  rf   r   r   r?   r   modelsr   s                       r   _model_flow_xai_oauthr#    sD   	 	 	 3&(Fzz+HI0@
 X78G$..#GD,$FG#D)T:	 !%k2$( xXY	 **lE BCi6I Y(9+(FG *H57IIj)/R668??DP "&&{3X7G7K7KE7RXVXYF&v]=y\bvVWyhxzH8$#K:&xj0^_`lY  23 se,-  	./ 	N3%()	  sP   .AG AG? =H8 G<G<$G77G<?H5H5H00H58	IIc                4   ddl m} ddlm}m}m}m}m}m} ddl	m
}	  |       }
|
j                  d      sft        d       t        d       |
j                  d      }|rt        d	|        |
j                  d
      rt        d|
j                  d
              yd}	  |d      } |	|d   |d         }|st        |      }|xs	 |r|d   nd} |||d|      }|r! ||        |d|       t        d| d       yt        d       y# t        $ r Y `w xY w)zAQwen OAuth provider: reuse local Qwen CLI login, then pick model.r   )_DEFAULT_QWEN_PORTAL_MODELS)get_qwen_auth_status resolve_qwen_runtime_credentialsrm   rn   r   DEFAULT_QWEN_BASE_URLfetch_api_modelsr  zNot logged into Qwen CLI OAuth.zRun: qwen auth qwen-oauth	auth_filezExpected credentials file: errorzError: NT)refresh_if_expiringrs   r?   zqwen3-coder-plusz
qwen-oauthr   r   r   r   z (via Qwen OAuth)r   )r   r%  r6   r&  r'  rm   rn   r   r(  r   r*  r<   rZ   r>   r;   )r!  r   r%  r&  r'  rm   rn   r   r(  r*  r  r+  r"  r   r   r   s                   r   _model_flow_qwen_oauthr/    s/   ;  3!#F::k"/0)*JJ{+	/	{;<::gGFJJw/012 F0TJ!%	"2E*4EF 12LVq	9KG&%.	H 8$#L2GH&xj0ABCl#  s   D 	DDc           
        ddl m}m}m}m}m}m}m}	m}
m	}  |d      }|r|j                  d      slt        d       t                	 t        j                  t        |dd      xs dt        t        |d	d
            t        |dd      xs d      } |
||d          	  |       }ddlm} |j                  dg       } |||d|d         }|sy ||        |d|d          t        d|        y# t         $ r t        d       Y yt"        $ r}t        d|        Y d}~yd}~ww xY w# |$ r}t         |	|             Y d}~yd}~ww xY w)z:MiniMax OAuth provider: ensure logged in, then pick model.r   )	r   rm   rn   r   )resolve_minimax_oauth_runtime_credentialsr   r   _login_minimax_oauthr   zminimax-oauthr   z0Not logged into MiniMax. Starting OAuth login...regionNglobalr   Fr   r   )r3  r   r   r   r   r  r?   )r   r   u   ✓ Using MiniMax model: )r6   r   rm   rn   r   r1  r   r   r2  r   r<   rZ   r   r   r   r   r   r>   r   r  )r   r   r   r   rm   rn   r   r1  r   r   r2  r   r   r   r   r   r  rz   r   s                      r   _model_flow_minimax_oauthr5    s[   
 
 
 $O4E		.1@A	 **tXt4@lE BCi6>$I
 !,=o,NO9;
 3 $$_b9I&(z*	H x z1BC	(

345  	./ 	N3%()	  $%s7   AC3 D, 3D)	D)D$$D),E1EEc           
     x  % ddl m}m}m} ddlm}m} ddlm}m	}m
} ddlm}	  |d      xs d}
 |d      xs d}t        d	       |
rt        d
|
        |rt        d|dd  d       t                	 t        d|
xs d d      j                         } |	d|r|dd dz   nd d      j                         }|s|
st        d       y|xs |
}|j%                  d      st        d| d       y|xs |}|j'                  d      j)                         %t+        %fddD              }|r%j-                  d      st                t        d       t        d       t        d|j'                  d       d       	 t        d       j                         j)                         }|d"v r&|j'                  d      dz   }|r|}t        d#|        t                dd$lm}  |||      }|j3                  d%      r-|j3                  d&      rt        d'|d&    d(       |d&   }|r|}n|j3                  d)      >t        d*|j3                  d+       d,t5        |j3                  d)      xs g        d-       nbt        d.|j3                  d+       d/       |j3                  d0      r3|d0   }|j-                  d      rt        d1|        nt        d2|        | j3                  d3      }d}t7        |t8              r,t;        |j3                  d4      xs d      j                         } |||5      }|rt        d6|        nt        d7       d}|j3                  d)      xs g }	 t5        |      d8k(  r\t        d9|d           t        d:      j                         j)                         }|d"v r|d   }nt        d;      j                         }nt5        |      d8kD  rt        d<       t=        |d8      D ]  \  }}t        d=| d>|         t        d?t5        |       d@      j                         }|j?                         r2d8tA        |      cxk  rt5        |      k  rn n|tA        |      d8z
     }n|r|}nt        d;      j                         }t        dA      j                         } ||      }t        dB| d      j                         xs |} d}!|rC	 tA        |jC                  dCd      jC                  dDdE      jC                  dFdE            }!|!dk  rd}!|r ||        |       }"|"j3                  d3      }#t7        |#t8              s|#rdI|#ini }#|#|"d3<   dJ|#dK<   ||#dL<   |r||#dM<   |r||#d4<   n|#jG                  d4d        ||"        |        t9        |#      | d3<   t        dN| dO| dP       no|s|r |        | j3                  d3      }$t7        |$t8              s|$rdI|$ini }$dJ|$dK<   ||$dL<   |r||$dM<   |r||$d4<   n|$jG                  d4d       |$| d3<   t        dQ        ||||xs d|!| |R       tI        || S       y# t         t"        f$ r t        d       Y yw xY w# t         t"        f$ r d!}Y w xY w# t         t"        f$ r t        d       Y yw xY w# tD        $ r t        dG| dH       d}!Y w xY w)TzCustom endpoint: collect URL, API key, and model name.

    Automatically saves the endpoint to ``custom_providers`` in config.yaml
    so it appears in the provider menu on subsequent runs.
    r   )_auto_provider_name!_prompt_custom_api_mode_selection_save_custom_providerr   )rp   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  
 y wr    )r   h
_url_lowers     r   r"   z%_model_flow_custom.<locals>.<genexpr>l  s       	
Zs   )	localhostz	127.0.0.1z0.0.0.0z:11434z:8080z:5000z/v1z+  Hint: Did you mean to add /v1 at the end?z@  Most local model servers (Ollama, vLLM, llama.cpp) require it.z  e.g. z  Add /v1? [Y/n]: r   >   r   yyesz  Updated URL: )probe_api_modelsused_fallbackresolved_base_urlz)Warning: endpoint verification worked at zL/models, not the exact URL you entered. Saving the working base URL instead.r"  zVerified endpoint via 
probed_url (z model(s) visible)z,Warning: could not verify this endpoint via z. Hermes will still save it.suggested_base_urlz8  If this server expects /v1 in the path, try base URL: z-  If /v1 should not be in the base URL, try: r   r   )current_api_modez  API mode: z  API mode: auto-detectrP   z  Detected model: z  Use this model? [Y/n]: z&Model name (e.g. gpt-4, llama-3-70b): z  Available models:r   rT   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.r   customr   r?   rs   r    (via )zFEndpoint saved. Use `/model` in chat or `hermes model` to set a model.)context_lengthru   r   r*   )%r   r7  r8  r9  r6   rn   ro   r   rp   r   r   hermes_cli.secret_promptr;  rZ   r\   r]   r^   r_   r   r   r   anyendswithr   rL  r<   r   r7   r8   r:   r[   isdigitr   replacer   r   rH   )&r   r7  r8  r9  rn   ro   rp   r   r   r;  current_urlcurrent_keyr?   rs   effective_urleffective_key_looks_local_add_v1rL  probe	suggestedr  rR  r   
model_namedetected_modelsconfirmrc   mpickcontext_length_strr   display_namerZ  r   r   _caller_modelrH  s&                                        @r   _model_flow_customrp  <  sL    nmGII= 128bK 017RK	
<=}-.BQ045	G	[M,MNcR

%' 	 ';BQ%/JOsS

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

 	:599\;R:S T) *	
 99)*23I!!%(NykZ Ei[QR 

7+#T*044Z@FBGMMO0)H XJ'('( Jii)/RO1$&q'9&:;<78>>@FFHG**,Q/
"#KLRRT
!A%'(!/15 '1QCr!o&'$S%9$::JKeg  ||~!s4y"HC4H"H,SY];
!
GHNNPJ"F

%' 	
 +=9~l^3?@FFHXL
 N
	" "**33e$e$N
 "!%
 :& m %&*/Y&RE CL$j)j,E) (E*IIj$'C u+w&zl&qIJw! 

7+-.:GY6RM$,j!$1j!'4M)$(0M*%j$/'wVW b% 4"} x( n> "8, 	G	l x( n  	",-?,@@VWX!N	"sK   6AY ='Y# #E0Y; AZ Y Y #Y87Y8;ZZZ98Z9c                4   ddl m}m} ddlm}m}m}m} ddlm	} | j                  di       }	t        |	t              r|	j                  d      dk(  rt        |	j                  dd	      xs d	      }
t        |	j                  d
d	      xs d	      }t        |	j                  d      xs d      j                         j                         xs d}|	j                  d      xs i }t        |t              r|ni }nd	}
d	}d}i } |d      xs 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!                	 |
xs d }t#        d!| d"      j                         }|xs |
j)                  d$      }|st!        d%       y|j+                  d&      st!        d'| d(       yt!                t!        d)       t!        d*       t!        d+       t!        d,       t!        d-       	 |dk(  rd.nd/}t#        d0| d1      j                         xs |}|d.k(  }|rdnd}d	}i }d}d	}|r	 dd2lm}m}m}m}m}  |rct!                         st!        d6       t!        d7       t        |j                  d8      xs d	      j                         }"|"xs }i }|"r|"|d8<   t!                t!        d9        |:      }# |#d;<      }$|$j                  d=      r=|$j                  d>      xs g }%|%rd?j;                  |%      nd@}&t!        dA|& dB| dC       n|$j                  dD      xs dE}'|$j                  dF      xs dG}(t!        dH|'        t!        dI|(        	 t#        dJ      j                         j                         })|)r|)dKvrt!        dL       y	  |#M      }nIt!                ddOlm }* 	  |*dP|r|dd dQz   ndR d"      j                         }+|+xs |}|st!        dS       yt!                t!        dT       |jC                  |||U      },tE        |,jF                        }-|,jH                  xs d	}.|.rW|.dk(  rdnd}/t!        dV|/        |,jJ                  rt!        dW|,jJ                   dC       |-rt!        dXtM        |-       dY       nt!        dZ|,jJ                          t!                t!        d[       t!        d\       t!        d]       t!        d^       t!        d_       	 |d`k(  rd.nd/}0t#        da|0 d1      j                         xs |0}1|1d.k(  rd`nd}.t!                d	}2|-rt!        db       tO        |-ddc dde      D ]  \  }3}4t!        df|3dgdh|4         tM        |-      dckD  rt!        ditM        |-      dcz
   dj       t!                	 t#        dk|xs |-d    d"      j                         }5|5s
|xs |-d   }2nw|5jQ                         r<ddtS        |5      cxk  rtU        tM        |-      dc      k  rn n|-tS        |5      ddz
     }2n+|5}2n(	 t#        dl|xs dm d"      j                         }6|6xs |}2|2st!        dn       y|jW                  |2|||U      }7|s	 |d|        |       }8|8j                  d      }9t        |9t              s|9rdo|9ini }9|9|8d<   d|9d<   ||9d<   |.|9d
<   |2|9do<   ||9d<   tY        |9d5p       |r2i }:d:D ]  };|j                  |;      }<|<s|<|:|;<    |: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}       t!                yt!        d~       t!                y# t$        t&        f$ r t!        d#       Y yw xY w# t$        t&        f$ r t!        d#       Y yw xY w# t8        $ r2}!t!                t!        d3|!        t!        d4       d5}d}Y d}!~!d}!~!ww xY w# t$        t&        f$ r t!        d#       Y yw xY w# t<        $ r}!t!        dN|!        d}Y d}!~!d}!~!ww xY w# t$        t&        f$ r t!        d#       Y yw xY w# t$        t&        f$ r t!        d#       Y yw xY w# t$        t&        f$ r t!        d#       Y yw xY w# t$        t&        f$ r t!        d#       Y yw xY w)uk  Azure Foundry provider: configure endpoint, auth mode, API mode, and model.

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

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

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

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

    Context lengths for the chosen model are resolved via the standard
    :func:`agent.model_metadata.get_model_context_length` chain
    (models.dev, provider metadata, hardcoded family fallbacks).
    r   r   rp   r   r   r   )azure_detectr   r   zazure-foundryr?   r   r   	auth_moders   entraAZURE_FOUNDRY_API_KEYzAzure Foundry Configurationz2==================================================z9Azure Foundry can host models with either OpenAI-style orz6Anthropic-style API endpoints.  Hermes will probe yourz6endpoint to auto-detect the transport and the deployedzmodels when possible.z  Current endpoint:  r   zOpenAI-stylezAnthropic-stylez  Current API mode:  entra_idz1  Current auth mode: Microsoft Entra ID (keyless)z  Current auth mode: API key (Nr<  z...)zhe.g. https://<resource>.openai.azure.com/openai/v1 or https://<resource>.services.ai.azure.com/anthropiczAPI endpoint URL [r   r@  r   z$No endpoint URL provided. Cancelled.rA  rC  rD  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.rW   rV   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=rY  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]: )rJ  rK  
Cancelled.)r   u0   ⚠ Could not build token provider for probing: r:  r>  r=  requiredzNo API key provided. Cancelled.u;   ◐ Probing endpoint to auto-detect transport and models...)rs   token_provideru   ✓ Detected API transport: z    (u
   ✓ Found z# deployed model(s) on this endpointu   ⚠ Auto-detection incomplete: z7Select the API format your Azure Foundry endpoint uses:z.  1. OpenAI-style  (POST /v1/chat/completions)z:     For: GPT models, Llama, Mistral, and most open modelsz)  2. Anthropic-style  (POST /v1/messages)z9     For: Claude models deployed via Anthropic API formatanthropic_messageszAPI format [1/2] (z"Available models on this endpoint:   rP   r   rS   z>2rT   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   rZ  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: rS  z tokenszA    Context length: not auto-detected (will fall back at runtime))-r6   rn   ro   r   rp   r   r   r   
hermes_clirs  r<   r7   r8   r:   r]   r   rZ   r\   r^   r_   r   r   agent.azure_identity_adapterrx  ry  rz  r{  r|  ImportErrorjoinr>   r[  r;  detectr;   r"  r   reasonr   r[   r^  r   r   lookup_context_lengthr   )>r   r   rn   ro   rp   r   r   r   rs  r  current_base_urlrR  current_auth_mode
_cur_entracurrent_entracurrent_api_key_lbl_placeholderr?   rb  _auth_defaultauth_choice	use_entraauth_mode_labelrc  entra_overridesr  entra_scoperx  ry  rz  r{  r|  r   _persisted_scope_overrider!  infor  tagerrr  ansr;  rs   	detectiondiscovered_modelsr   
mode_labeldefault_choicemode_choiceeffective_modelrc   r!   rl  rh  ctx_lenr   r   clean_entrakeyval
auth_labels>                                                                 r   _model_flow_azure_foundryr    s
   B H  ( 

7B'I)T"y}}Z'@O'Sy}}Z<BCy}}Z<BC	k : GiHNNPVVXe\e]]7+1r
&0T&B
%#$;<BO	G	
'(	(O	G	
EF	
BC	
BC	
!"	G%&6%789  #55 " 	
 	%dV,-J&AB	.r/B.C4HI	G FF 	
  c2

%' 	 1!199#>M45##$;<m_,RST 
G	
	
IJ	
[\	
ef	
KL0J>C/cBCIIK  	 s"I$-j9O MONK	(  +-JK3 %((9(9'(B(Hb$I$O$O$Q!/I3I$'@OG$NO%
 *$O88D>((=17RK,7$))K(_C1#h{m1MN((7#C'CC88F# K  D,HTF#$RSYY[aac s,.l#
	"1AN
 	A	*?OBQ/%7PZ[[^_eg   2?34 
G	
GH##% $ I $(	(8(8#9&&,"H&*<<NBS 	 	,ZL9:E)**+1-.S!2344WX 	/	0@0@/ABCGH>?JK9:IJ	$48L$LSRUN*>*:#>?EEG "!  ,7#+='CU 
GO23 1#2 6a@ 	&FAsBqfBse$%	& !B&S!23b899`a 		=m>cO`abOc=ddgheg  +C/@/CO\\^SY Q#c:K6Lb2Q Q/D	A>O"O	+M,^=^+__bceg  %523 00%	 1 G .>
-CGGGEeT"&+E"G'E*%E* E*&E)(E+$U5A  	'C!%%c*C#&C 	' (E'Ngeg")5kF7O &'("-%&',#+/A#AGXJ*3&  
G	
)*	 
01	 
-.	 
-.	  1
23$WQKw78 
G 	QR	Gc x( n2 x( n*  	(GA#GH34I'O	(^ &x0 n%  	"DSEJK!N	" "8, 	.!	\ "8, 	.!	* "8, 	.!	 "8, 	.!	s   #a -*a5 -b 'c 	c3 2$d +*d: $e !e: a21a25bb	c'ccc0/c03	d<ddd76d7:eee76e7:ffc           	     r   ddl m}m}m} ddlm}m} ddlm}m	} ddl
m}	 |d   }
|d   }|j                  dd	      }|j                  d
d	      }|j                  dd	      }|j                  dd	      }|j                  d      xs d	j                         }|s"|r t        j                  j                  |d	      } |||      }|j                  dd      }t!        |t"              r|j%                         dv}g }|j                  di       }t!        |t&              r3|D cg c]'  }t#        |      j                         st#        |      ) }}nJt!        |t(              r:|D cg c]/  }t!        |t"              s|j                         s%t#        |      1 }}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|j/                  |      }t+        dt-        |       d       	 ddlm} |D cg c]  }||k(  r| dn| c}dgz   } |d|
 d||d d!      }t+                |dk  s|t-        |      k\  rt+        d"       y#||   }nc|r.t+        d+       	 tA        d,| d)      j                         xs |}n3t+        d-       	 tA        d.      j                         }|st+        d/       y# ||        |       } | j                  d      }!t!        |!t&              s|!rd0|!ini }!|!| d<   |rYd1|j                         j%                         jK                  d2d3      z   |!d4<   |!jM                  dd#       |!jM                  d
d#       nd5|!d4<    |||      |!d<   |r||!d
<   |j                  dd	      }"|"r|"|!d<   n|!jM                  dd#        ||         |        |r0 |       } | j                  d6      }#t!        |#t&              r|#j                  |      }$t!        |$t&              r||$d7<   t#        |j                  d8d	      xs d	      j                         }%t#        |j                  d
d	      xs d	      j                         }&tO        |%xs |&      }'|'r4|r2t#        |$j                  d
d	      xs d	      j                         s||$d
<   |r2t#        |$j                  dd	      xs d	      j                         s||$d<   |#| d6<    ||        n |||||9       t+        d:|        t+        d;|
 d<| d=       y#c c}w c c}w c c}w # 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)      j                         }|st+        d"       Y y#tC        |      d$z
  }|dk  s|t-        |      k\  rt+        d"       Y y#||   }n&# tD        tF        tH        f$ r t+        d*       Y Y y#w xY wY hw xY w# tF        tH        f$ r t+        d*       Y y#w xY w# tF        tH        f$ r t+        d*       Y y#w xY w)>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_valuer9  r   r   r)  ru   r?   r   r   rs   key_envr   provider_keydiscover_modelsT>   0nofalser"  z  Provider: z  URL:      z  Current:  z2Using configured models (discover_models: false): zFetching available models...r   g       @zFound z model(s):
)curses_radiolistz
 (current)rJ   zSelect model from r   )r   cancel_returns
searchabler  NrP   rS   rT   z. Cancelz
Choice [1-r   r@  z%Could not fetch models from endpoint.zModel name [z@Could not fetch models from endpoint. Enter model name manually.Model name: zNo model specified. Cancelled.r   zcustom:rR   -r   rW  	providersdefault_modelapi_key_ref)r   u   
✅ Model set to: z   Provider: rP  rY  )(r   r  r  r9  r6   rn   ro   r   r   r   r   r*  r<   r]   osenvironr7   r:   r   r8   r;   rZ   r   r   hermes_cli.curses_uir  r  NotImplementedErrorOSError
subprocessSubprocessErrorr[   r\   r   r   r^   r_   r_  r   r   )(r   provider_infor  r  r9  rn   ro   r   r   r*  ru   r?   r   rs   r  saved_modelr  config_api_keydiscoverconfigured_models
cfg_modelsrk  r"  fetch_kwargsr   r  
menu_itemsrb   rh  rc   r   r  r   r   custom_api_modeproviders_cfgprovider_entryoriginal_api_key_reforiginal_api_keyhad_inline_api_keys(                                           r   _model_flow_named_customr    s    E  EG:2 DZ(H  R0H	2.G	2.G##GR0K!%%n5;BBDL w**.."-:='RN   !2D9H(C >>#+??#%""8R0J*d#-7J3q6<<>SVJJ	J	%&
*Q*<CF
 
 
L
 	L

#$[M*+	G)B3GXCYBZ[\",-!3''/L$!'8D|D +&F;&0 ,,{3Ks6{m<01$	= FL@AA$41#Z !;
J #$TF!,$!C GQw#V,l#J( 
56	k]#>?EEGV;J
 	PQ	~.446J 23 z"
-CGGGEeT"&+E"G%(:(:(<(B(B(D(L(LSRU(VVj		*d#		)T"$jB8
j -E)#''
B7O+j		*d# m,mT**..|<N.$/2</ (+!%%mR8>B(%' % $'}'8'8B'G'M2#N#T#T#V %)*>*RBR%S"&& 2 29b A GRHNNP0>N9-3~'9'9)R'H'NB#O#U#U#W07N9-#0K C  	h
XV	 
-.	M$r(1
-.q K
D 0':;U;UV 	!&!, -1)*k)9r1#Rs6(+,- Bs6{Q'x01GjVq(9=>DDF,'#hl7cS[0,'#C[
 18< n% 	. "8, 	.!	 "8, 	.!	s   U>U"U8U	U
U' U"#A U' $U' 8!Y9 &Z "U' 'A8Y6 6Y,YYY6Y/+Y6.Y//Y65Y69ZZZ65Z6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}||   } |	|      }|j+                  dd      }|j+                  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      j1                         }|dk(  r<	 ddlm}  |       }|r |
d|       t-        d       t-                nt-        d       yn|dk(  rnddlm} 	  |d      j1                         }|st-        d       y	 dd lm }  ||      \  }} |st-        d!|         y	  |
d|       t-        d"       t-                nt-        d       y |	|      }|j+                  dd      }|j+                  d	d      }nP|d#v r&dd$l"m#}!  |!|      }"t-        d%|dd&  d'| |" d(       n|d)k(  rt-        d*       nt-        d+       t-                |jH                  }# ||      }$|$r2|$D %cg c]&  }%|%j+                  d,      s|%j+                  d,d      ( c}%n |||#      }& |||$|-      xs |}'|&r+|&D (cg c]  }(|(s|(	 })}(t-        d.tK        |)       d/       n*|j+                  |g       })|)rt-        d0       t-        d1       |)r ||)|'||#|2      }*n	 t/        d3      j1                         }*|*r ||*|$|-      xs |*}* |       }+ ||+      }, ||*|$|-      }-d}.|-rt-        d4|* d5        ||-|,6      }. ||*        |       }/|/j+                  d7      }0tM        |0tN              s|0rd8|0ini }0|0|/d7<   ||0d9<   |#|0d:<    ||*|$|-      |0d;<   tQ        |0d<=       |.	 ||/|.        ||/        |        t-        d>|* d?|jR                   d(       |-r#|.d@k(  rt-        dA       y|.rt-        dB|.        yyyt-        dC       y# t2        t4        f$ r t-                Y yw xY w# t:        $ r}t-        d|        Y d}~yd}~ww xY w# t2        t4        f$ r t-                Y yw xY w# tB        $ r Y 
w xY wc c}%w c c}(w # t2        t4        f$ r d}*Y w xY w)DzAGitHub Copilot flow using env vars, gh CLI, or OAuth device code.r   )_current_reasoning_effort"_prompt_reasoning_effort_selection_set_reasoning_effort)r   rm   rn   ro   $resolve_api_key_provider_credentials)r   r   r   )r  r*  fetch_github_model_cataloggithub_model_reasoning_effortscopilot_model_api_modenormalize_copilot_model_idcopilotrs   r   r1   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]: NrV   )copilot_device_code_loginCOPILOT_GITHUB_TOKENz  Copilot token saved.z  Login cancelled or failed.z  Login failed: rW   r:  z   Token (COPILOT_GITHUB_TOKEN):   Cancelled.)validate_copilot_tokenu     ✗ z  Token saved.>   GH_TOKENGITHUB_TOKENformat_secret_source_suffixz  GitHub token: r<  u	   ... ✓ (rY  zgh auth tokenu*     GitHub token: ✓ (from `gh auth token`)u     GitHub token: ✓r3   catalogrs     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  rS   z supports reasoning controls.)current_effortr   r   r   r?   r   Fr   r   rX  nonez"Reasoning disabled for this model.zReasoning effort set to: r   )*r   r  r  r  r6   r   rm   rn   ro   r  r   r   r   r   r   r  r*  r  r  r  r  r<   rZ   r\   r]   r^   r_   hermes_cli.copilot_authr  r>   r[  r;  r  r  hermes_cli.env_loaderr  inference_base_urlr   r7   r8   r   ru   )1r   r   r  r  r  r   rm   rn   ro   r  r   r   r   r  r*  r  r  r  r  ry   r   r   rs   r1   rf   r  tokenr   r;  new_keyr  validr   r  	bw_suffixeffective_baser  itemlive_modelsnormalized_current_modelr'   
model_listr   initial_cfgr  reasoning_effortsselected_effortr   r   s1                                                    r   _model_flow_copilotr  L  s6   tt  KJ  K,G0=Eii	2&GYYx$F>?()Z	
 	YZMNQRlAB-.o	-.446F
 S=M13"#95A23G89  s]E./QRXXZ n%J3G<
sF3%.) 
 17;"#G.!4[A))Ir*8R(11I3F;I$WRa[M6(9+QOP&>?'(//N(1G  )0B488D>$	Bg~6  	#	
 	
   /:G8hhG
GZ))FGH%))+r:
^ ST*2(+#
	^,224H & 
  	 "m2;?:

 Bxj =>?@!.O 	8$m %&*/Y&RE CL'j*j2
j
 	)uE&!#7C&xjw||nAFG&(:; 1/1BCD !  	lq "8, 	G	   (./ &x0   6 	C H* "8, 	H	sx   6Q  9Q R !R" &R2=R22R7:R7R<  QQ	R (Q;;R RR"	R/.R/<SSc                d   ddl m}m}m}m}m}m}m} ddlm	}	m
}
m} ddlm}m} ~ d}||   } ||      }|j                  d      xs |j                  d      xs d}|j                  d	      xs |j                   }t#        d
       t#        d       t#        d       t#        d|        t#        d|        t#                	  ||      }|j                  d	      xs |}d}	  |d      }|j                  dd      } |
|      } ||||      xs |}|rJ|D cg c]&  }|j                  d      s|j                  dd      ( }}t#        dt'        |       d       n*|	j                  dg       }|rt#        d       t#        d       |r ||||||      }n	 t)        d      j+                         }|st#        d       y ||||      xs |} ||        |       }|j                  d      }t1        |t2              s|rd|ini }||d<   ||d<   ||d	<   d |d!<   t5        |d"#        ||        |        t#        d$| d%|j6                   d&       y# t$        $ r#}t#        d|        t#        d       Y d}~yd}~ww xY w# t$        $ r Y w xY wc c}w # t,        t.        f$ r d}Y w xY w)'z4GitHub Copilot ACP flow using the local Copilot CLI.r   )r   rm   rn   ro   $get_external_process_provider_statusr  -resolve_external_process_provider_credentials)r  r  r  r   zcopilot-acpresolved_commandcommandr  r?   z?  GitHub Copilot ACP delegates Hermes turns to `copilot --acp`.zB  Hermes currently starts its own ACP subprocess for each request.zH  Hermes uses your selected model as a hint for the Copilot ACP session.z  Command: z  Backend marker: u     ⚠ z[  Set HERMES_COPILOT_ACP_COMMAND or COPILOT_CLI_PATH if Copilot CLI is installed elsewhere.Nr   rs   r  r3   r  r  r  r  r  r  r   r   r   r   r   r   Fr   r   rX  rY  )r6   r   rm   rn   ro   r  r  r   r   r  r  r  r   r   r   r<   r  rZ   r>   r   r\   r]   r^   r_   r7   r8   r   ru   )r   r   r   rm   rn   ro   r  r  r   r  r  r  r   r   ry   r   r  r  r  r   r   catalog_api_keycatalog_credsr  r  r  r  r   r   r   s                                 r   _model_flow_copilot_acpr    s      
 ;K,G1+>F

%&L&**Y*?L9  ZZ
+Iw/I/IN	
KL	
NO	
TU	K()
*+	~.
/0	G=kJ YYz*<nNO<YG'++Ir: )9G"#	
 	
   5<OTdhhtR(O
OZ))FGH%)))R8
^ ST*2(++
	^,224H l 	##	
 	
   x 
-CGGGEeT"&+E"G#E*&E**E*$U5A	"8*F7<<.
BC[  seni	
 	   P* "8, 	H	sH   I $J J2JJ 	J I>>J	JJJ/.J/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                  r|j                  d   nd}|j                   xs d}d}|j                  D ]&  } ||      xs t#        j$                  |d      }|s& n  ||||      \  }}|ry	|j'                  d
      }|r|}t)        d|        n|j*                  }t)        d|        |r ||      r	 |	|d       t)                |j-                  |rdndg       }|r ||||||      }n	 t/        d      j1                         }|r ||        |
       }|j-                  d      }t7        |t8              s|rd|ini }||d<   ||d<   ||d<   |j;                  dd	       t=        |d        ||        |        |rdnd}t)        d| d| d       y	t)        d       y	# t2        t4        f$ r d	}Y w xY w)u  Kimi / Moonshot model selection with automatic endpoint routing.

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

    No manual base URL prompt — endpoint is determined by key prefix.
    r   ri   )r   KIMI_CODE_BASE_URLrm   rn   ro   rr  r  zkimi-codingr   rx   Nzsk-kimi-u$     Detected Kimi Coding Plan key → u     Using Moonshot endpoint → moonshotr  zEnter model name: r   r   r   r?   r   Fr   zKimi CodingMoonshotr   rX  rY  r   )r   rj   r6   r   r  rm   rn   ro   r   rp   r   r   r   r   r  rw   base_url_env_varr  getenvr   rZ   r  r<   r\   r]   r^   r_   r7   r8   r   r   )r   r   rj   r   r  rm   rn   ro   rp   r   r   r   r  ry   r   r  base_url_envr   evr   is_coding_planr  r  r   r   r   endpoint_labels                              r   _model_flow_kimir    s'    0   3K,G-4-E-Eg&&q)2G++1rL L&& $R(=BIIb",=
 *;L%  ",,Z8N+4^4DEF 33.~.>?@l3|R(	G "%%~m:WYZJ*'(+(
	1288:H 8$ m %&*/Y&RE CL'j*j		*d#(uEC*8j&xj~6FaHIl- "8, 	H	s   %G G.-G.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$                  r|j$                  d   nd}|j&                  xs d}d}|j$                  D ]&  } |
|      xs t)        j*                  |d      }|s& n  ||||      \  }}|ry	d}|r  |
|      xs t)        j*                  |d      }|sM| j-                  d
      }t/        |t0              r,t3        |j-                  d      xs d      j5                         } ||xs |j6                        }dd |d       dfdd |d       dfg}g }|D ]5  \  }}||k(  r|j9                  d|| df       #|j;                  ||f       7 |j;                  d        ||D cg c]  \  }}|	 c}}      }|||   d   dk(  rt=        d       y	||   d   }  ||       }!|r	 |||!        |||!      }"|"r(|"}#t=        dt?        |#       d|j@                   d       n-|j-                  |g       }#|#rt=        d|j@                   d       |#r ||#|||!|      }$n	 tC        d      j5                         }$|$r ||$        |       }%|%j-                  d
      }&t/        |&t0              s|&rd|&ini }&|&|%d
<   ||&d<   |!|&d<   |&jI                  dd	       tK        |&d         ||%        |	        t1        |&      | d
<   t=        d!|$ d"|j@                   d       y	t=        d       y	c c}}w # tD        tF        f$ r d	}$Y w xY w)#z6StepFun Step Plan flow with region-specific endpoints.r   )_infer_stepfun_regionrj   _prompt_provider_choice_stepfun_base_url_for_regionr   rm   rn   ro   rr  )r  r*  stepfunr   rx   Nr   r?   internationalzInternational (rY  chinazChina (u     ← currently active)rO   rJ   rO   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   rX  )&r   r  rj   r  r  r6   r   rm   rn   ro   r   rp   r   r   r   r   r  r*  rw   r
  r  r  r<   r7   r8   r:   r]   r  insertr=   rZ   r   ru   r\   r^   r_   r   r   )'r   r   r  rj   r  r  r   rm   rn   ro   rp   r   r   r   r  r*  ry   r   r  r  r   r  r   current_baser  current_regionregion_choicesordered_regions
region_keyrd   _
region_idxselected_regionr  r  r  r   r   r   s'                                          r   _model_flow_stepfunr$    s   }}   EK,G-4-E-Eg&&q)2G++1rLL&& $R(=BIIb",=
 *;L% L$\2Qbiib6QJJw'	i&y}}Z8>B?EEGL*<+U7;U;UVN :?KLAN	
 
G8AB!DEN O+ 8
E'""1zeW<R3S&TU""J#67	8
 /0()PHAu%)PQJ_Z8;xGl%j1!4O1/BN|^4"<@K 
Z)dKL%))+r:
6w||n E6 6
 *'(+(
	^,224H 8$m %&*/Y&RE CL'j*j		*d#(uECu+w&xjw||nAFGlm *QB "8, 	H	s   "L"
L( (L<;L<c                L   ddl m}m}m} ddlm}m}m}m}	 ddl	m
}
 d| d} |d      xs d}|r#dd	lm}  |d      }t        d
|dd  d|        nYt        d|        t                ddlm} 	  |d
      j!                         }|st        d       y |	d|       |}t        d       t                |
j'                  dg       }t        dt)        |       d       |r |||d||      }n	 t+        d      j!                         }|r ||        |       }|j'                  d      }t-        |t.              s|rd|ini }||d<   d|d<   ||d<   |j1                  dd       t3        |d       |j'                  di       }t-        |t.              si }||d<   ||d<    |	d |        |	d!|        ||        |        t        d"| d#| d$       t        d|        yt        d%       y# t"        t$        f$ r t                Y yw xY w# t"        t$        f$ r d}Y w xY w)&u   Bedrock API Key mode — uses the OpenAI-compatible bedrock-mantle endpoint.

    For developers who don't have an AWS account but received a Bedrock API Key
    from their AWS admin. Works like any OpenAI-compatible endpoint.
    r   rm   rn   ro   )r   r   rp   r   r  zhttps://bedrock-mantle.z.api.aws/v1AWS_BEARER_TOKEN_BEDROCKr   r  z  Bedrock API Key: N      ... ✓z  Endpoint: r:  r       ✓ API key saved.bedrock
  Showing z curated modelsrW  r    Model ID: r   r   r   r?   r   Fr   r3  r   r     Default model set to: z (via Bedrock API Key, rY    No change.)r6   rm   rn   ro   r   r   r   rp   r   r   r  r  r  rZ   r[  r;  r]   r^   r_   r<   r   r\   r7   r8   r   r   )r   r3  r   rm   rn   ro   r   r   rp   r   r  mantle_base_urlr   r  source_suffixr;  rs   r  r   r   r   bedrock_cfgs                         r   _model_flow_bedrock_api_keyr3  W  s]    
  3/x{CO !!;<BLE34NO#L"$5#6gm_MN_-./A	*+@AGGIG .!17;$%	G "%%i4J	Js:'
78*'%,(
	^,224H 8$ m %&*/Y&RE CL$j+j		*d#(uE ggi,+t,K &H$I 	'6(/:C(
2I&QRST_-./ny "8, 	G	4 "8, 	H	s$   3G/ 2H /H
HH#"H#c                v   !" ddl m}m}m} ddlm}m} ddlm} 	 ddl	m
}m}	m}
m}  |       s t        d	       t        d
       t                 |	       }|rt        d| d       nt        d       t                 |
       }	 t!        d| d      j#                         }|xs |}t        d       t                t        d       t        d       t        d       t        d       t        d       t                	 t!        d      j#                         }|dk(  rt)        | ||       yt        d| d        ||      }|r<d}d}g }|D ]O  }|d   "t+        "fd|D              rt+        "fd|D              r2t-        "|      s?|j/                  |       Q t0        dz   t3               }|D ]<  }|d   "t5        "fd D        d      }|s |j7                  "t9        |      d        > g }|D ].  }|d   ""j;                        s"|v r|j/                  |       0 g d! d<fd"! !fd#}|j=                  |$       |D cg c]  }|d   	 }}t        d%t9        |       d&t9        |       d'       n9|j?                  d(g       }|rt        d)t9        |       d*       nt        d+       y|r |||d(d,| d-.      }n	 t!        d/      j#                         }|r ||        |       }|j?                  d0      }tA        |tB              s|rd1|ini }||d0<   d(|d2<   d,| d-|d3<   |jE                  d4d       tG        |d56       |j?                  d(i       }tA        |tB              si }||d7<   ||d(<    ||        |        t        d8| d9| d:       yt        d;       y# t        $ r# t        d       t        d       t                Y yw xY w# t$        t&        f$ r t                Y yw xY w# t$        t&        f$ r t                Y yw xY wc c}w # t$        t&        f$ r d}Y Nw xY w)=u$  AWS Bedrock provider: verify credentials, pick region, discover models.

    Uses the native Converse API via boto3 — not the OpenAI-compatible endpoint.
    Auth is handled by the AWS SDK default credential chain (env vars, profile,
    instance role), so no API key prompt is needed.
    r   r&  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]: rW   z  Discovering models in r=  )z
stability.zcohere.embedztwelvelabs.zus.stability.zus.cohere.embedzus.twelvelabs.zglobal.cohere.embedzglobal.twelvelabs.)	safeguardvoxtralzpalmyra-visionr3   c              3  @   K   | ]  }j                  |        y wr   r   r   s     r   r"   z&_model_flow_bedrock.<locals>.<genexpr>	  s     @3>>!$@s   c              3  B   K   | ]  }|j                         v   y wr   )r   )r   sr!   s     r   r"   z&_model_flow_bedrock.<locals>.<genexpr>	  s     A1		#As   )r$   c              3  F   K   | ]  }j                  |      s|  y wr   r   r   s     r   r"   z&_model_flow_bedrock.<locals>.<genexpr>	       Jaq8I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-scoutc                T     t         fdD        d       }|r t        |      d  S  S )Nc              3  F   K   | ]  }j                  |      s|  y wr   r   r   s     r   r"   z8_model_flow_bedrock.<locals>._base_id.<locals>.<genexpr>=	  r@  r#   )r%   r   )r!   _pp_PROFILE_PREFIXESs   ` r   _base_idz%_model_flow_bedrock.<locals>._base_id<	  s-    J#4JDQC%(3s3xy>1c1r   c                    | d   } |      }t              D ]1  \  }}|j                  |      sd||j                  d      sdnd|fc S  |j                  d      rddd|fS ddd|fS )Nr3   r   r$   rP      )r[   r   )rk  r!   baserc   rec_RECOMMENDED_BASESrE  s        r   	_sort_keyz&_model_flow_bedrock.<locals>._sort_key@	  s    D'CC=D#$67 R3??3'q3>>)+D!!SQQR ~~i(1a~%q!S>!r   )r  r  z text model(s) (filtered from z total)r+  z  Using z, curated models (live discovery unavailable)zJ  No models found. Check IAM permissions for bedrock:ListFoundationModels.zhttps://bedrock-runtime.z.amazonaws.comr.  r-  r   r   r   r?   r   Fr   r3  r.  z (via AWS Bedrock, rY  r/  )r!   r:   returnr:   )$r6   rm   rn   ro   r   r   r   r   r  agent.bedrock_adapterr5  r6  r7  r8  r  rZ   r\   r]   r^   r_   r3  r\  r)   r=   r&   setr%   addr   r   sortr<   r7   r8   r   r   )#r   r   rm   rn   ro   r   r   r  r5  r6  r7  r8  auth_varr  region_inputr3  r  r  _EXCLUDE_PREFIXES_EXCLUDE_SUBSTRINGSfilteredrk  profile_base_idsrC  dedupedrK  r  r   r   r   r2  rD  rJ  rE  r!   s#                                  @@@@r   _model_flow_bedrockrX    s    
 ;2	
 	
  LMUV')H#H:T23LM	G ,-N~n-=SABHHJ +^F 

+,	G	
56	
NO	
"#	
HI	
AB	G,-335
 c#FFMB 
$VHC
01)&1K	
 I  	AD'C@.?@@A-@AA5c6BOOA	 1<?5 	5AD'CJ#4JDQC $$SS^4		5  	AD'CNN#45++NN1	

	2		" 	#'./!ag/
/s:''Ec+FVEWW^_	
 &)))R8
3z?++WX \  *'&7x~N	
	^,224H 8$m %&*/Y&RE CL%j6vhnMj		*d#(uEggi,+t,K &H$IC(
2EfXQOPni  >?%&	, x(   x( p 06 "8, 	H	sM   N1 O  O? PP# 1)OO O<;O<?PP#P87P8c                H   ddl m}m}m} ddlm}m}m} ddlm	}  |d      xs  |d      xs dj                         }	|	rt        d|	 d	       n,t        d
       t        d       t        d       t        d       t                 |       }
|
j                  d      }t        |t              si }t        |j                  d      xs d      j                         }	 t!        d|xs d d      j                         }|xs |}t        |j                  d      xs d      j                         xs d}	 t!        d| d      j                         }|xs |}|j                  dg       xs ddg}|dk(  rd| dnd| d| d} |||d|      }|r ||        |       }
|
j                  d      }t        |t              s|rd|ini }||
d<   d|d <   |j'                  d!d       |j'                  d"d       t)        |d#$       |
j                  d      }t        |t              si }||d<   ||d<   ||
d<    ||
        |        t        d%| d&| d'       yt        d(       y# t"        t$        f$ r t                Y yw xY w# t"        t$        f$ r t                Y yw xY w))u  Google Vertex AI provider: Gemini via the OpenAI-compatible endpoint.

    Auth is OAuth2 — short-lived tokens minted from a service-account JSON or
    Application Default Credentials (ADC). No static API key. The credential
    *path* lives in .env (VERTEX_CREDENTIALS_PATH / GOOGLE_APPLICATION_CREDENTIALS);
    project ID and region are non-secret and saved to config.yaml under vertex:.
    r   r&  )r   r   rp   r  VERTEX_CREDENTIALS_PATHGOOGLE_APPLICATION_CREDENTIALSr   z,  Vertex credentials: service account JSON (u   ) ✓z;  Vertex credentials: Application Default Credentials (ADC)z5    Vertex uses OAuth2, not a static API key. Either:u9         • run 'gcloud auth application-default login', oruQ         • set VERTEX_CREDENTIALS_PATH in ~/.hermes/.env to a service account JSONvertex
project_idz  GCP project ID [zfrom credentialsr   Nr3  r4  z  Vertex region [zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-previewzGhttps://aiplatform.googleapis.com/v1beta1/projects/<project>/locations/z/endpoints/openapirB  z@-aiplatform.googleapis.com/v1beta1/projects/<project>/locations/r.  r   r   r   r?   r   Fr   r.  z (via Google Vertex AI, rY  r/  )r6   rm   rn   ro   r   r   r   rp   r   r  r]   rZ   r<   r7   r8   r:   r\   r^   r_   r   r   )r   r   rm   rn   ro   r   r   rp   r  sa_pathr   
vertex_cfgcurrent_projectproject_inputr]  r  rR  r3  r  base_url_previewr   r   vcfgs                          r   _model_flow_vertexrd  	  s    
 JI2 	/0 	9:	eg	 
 <WIUKLKLEFIJab	G
-C"Jj$'
 *..6<"=CCEO !F4F GsK

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

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

    Returns the selected base URL.  Falls back to *current_base* on cancel
    or error.
    r   )r  )ZAI_ENDPOINTSr   r   rP  rY  zCustom proxy URLzSelect Z.AI / GLM endpoint:)r   r`   zCustom base URL [r   rA  M     Invalid URL — must start with http:// or https://. Keeping current value.rP   )r   r  r6   rf  r]   r   r[   r   r=   r\   r^   r_   rZ   r   )r  r  rf  r!  urlrd   optionsnormalized_currentr   rb   ra   r   overrides                r   _select_zai_endpointrl  	  s    8- 5BBB 035s|BGB&,"335<<SA K"7+ 'XaC0K'
 g,K4;<jeS%3%q!<G<NN%&&+H
 3w<	 0cBCIIKH ""#:;abs##8Q&&s++Q C = "8, 	 G	 s   D7D>E E"!E"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$                  xs d}d}|j"                  D ]&  } ||      xs t'        j(                  |d      }|s& n  ||||      \  }}|ry|d	k(  r|r	 dd
lm} |t1        d       |r ||      ndxs( t'        j(                  |xs dd      xs |j2                  } |||      }|dk(  rt1                t1        d       t1        d       t1        d       t1        d       t1                t1        d       t1        d       t1                t1        d       t1                t1        d       y|dk(  rt1        d       nt1        d       t1                d}|r  ||      xs t'        j(                  |d      }|s	  |
       j5                  d      xs i }t7        |j5                  d      xs d      j9                         j;                         |k(  r,t7        |j5                  d      xs d      j9                         }|xs |j2                  }|dk(  r t=        |      }|r||k7  r|r	 |	||       |}nJ	 t?        d| d      j9                         }|r*|r(|jE                  d      st1        d       n |	||       |}|d k(  rDdd!lm#} dd"lm$} |xs |r ||      nd} 	  || |#      }!|!rt1        d&tK        |!       d'       n|d(k(  r>dd)lm&}# |xs |r ||      nd}  |#| |d*+      }!|!rt1        d&tK        |!       d,       nx|d-k(  rdd.lm} |xs |r ||      nd} |j5                  |g       }$ || |      }%|%r)|%}!t1        d&tK        |!       d/|jN                   d0       ng }&	 dd1l(m)}'  |'|      }&|&r|&D (ch c]  }(|(j;                          })}(tU        |&      }!|$D ]E  }(|(j;                         |)vs|!jW                  |(       |)jY                  |(j;                                G t1        d&tK        |!       d2       nw|$}!|!rrt1        d3tK        |!       d4       nX|j5                  |g       }$g }&	 dd1l(m)}'  |'|      }&|&r|$ru|&D (ch c]  }(|(j;                          })}(tU        |&      }*|$D ]E  }(|(j;                         |)vs|*jW                  |(       |)jY                  |(j;                                G |*}!n|&}!t1        d&tK        |!       d2       n|$r)tK        |$      d5k\  r|$}!t1        d3tK        |!       d4       nv|xs |r ||      nd}  || |      }%|%r?tK        |%      tK        |$      k\  r(|%}!t1        d&tK        |!       d/|jN                   d0       n|$}!|!rt1        d3tK        |!       d4       |d6v rD|!D +cg c]  }+ |||+       }!}+ |||      }tU        tZ        j]                  d7 |!D                    }!|!r$i },	 dd8lm/}-  |-|      xs i }, ||!||,|||9      }.n	 t?        d:      j9                         }.|.r|d6v r	 |||.      }. ||.        |
       }/|/j5                  d      }0ta        |0tZ              s|0rd;|0ini }0|0|/d<   ||0d<   ||0d<   tc        |0d<=       |d6v r |||.      |0d><   n|0je                  d>d        ||/        |        t1        d?|. d@|jN                   dA       yt1        dB       y# t.        $ r d}Y yw xY w# t.        $ r Y w xY w# t@        tB        f$ r t1                d}Y w xY w# |$ r&}"t1        d$|"        t1        d%       g }!Y d}"~"d}"~"ww xY w# t.        $ r Y w xY wc c}(w # t.        $ r Y w xY wc c}(w c c}+w # t.        $ r i },Y w xY w# t@        tB        f$ r d}.Y w xY w)CzCGeneric flow for API-key providers (z.ai, MiniMax, OpenCode, etc.).r   ri   r  rr  )r  r*  opencode_model_api_modenormalize_opencode_model_idr   rx   Ngemini)probe_gemini_tierz  Checking Gemini API tier...freeuW   ❌ This Google API key is on the free tier (<= 250 requests/day for gemini-2.5-flash).z[   Hermes typically makes 3-10 API calls per user turn (tool iterations + auxiliary tasks),zO   so the free tier is exhausted after a handful of messages and cannot sustainz   an agent session.zX   To use Gemini with Hermes, enable billing on your Google Cloud project and regeneratezK   the key in a billing-enabled project: https://aistudio.google.com/apikeyzY   Alternatives with workable free usage: DeepSeek, OpenRouter (free models), Groq, Nous.z*Not saving Gemini as the default provider.paidu     Tier check: paid ✓z3  Tier check: could not verify (proceeding anyway).r   r   r?   zaiz
Base URL [r   rA  rg  lmstudio)r   )fetch_lmstudio_models)rs   r?   z"  LM Studio rejected the request: zC  Set LM_API_KEY (or update it) to match the server's bearer token.r  z model(s) from LM Studiozollama-cloud)fetch_ollama_cloud_modelsT)rs   r?   r}   z model(s) from Ollama Cloudnovitar)  r  r  )list_agentic_modelsz" model(s) from models.dev registryr,  r   r<  >   opencode-goopencode-zenc              3  &   K   | ]	  }|s|  y wr   rF  )r   r!   s     r   r"   z/_model_flow_api_key_provider.<locals>.<genexpr>)  s     'IS'Is   )r{   r~   r  r   Fr   r   r   rX  rY  r   )3r   rj   r6   r   rm   rn   ro   r   rp   r   r   r   r   r  r*  rn  ro  rw   r
  r  r  agent.gemini_native_adapterrq  r>   rZ   r  r<   r:   r]   r   rl  r\   r^   r_   r   r   rv  r   rw  ru   agent.models_devry  r;   r=   rO  r8   fromkeysr{   r7   r   r   )1r   ry   r   rj   r   rm   rn   ro   rp   r   r   r   r  r*  rn  ro  r   r  r  r   r  r   rq  
probe_basetierr  _mr  chosen_baserk  r   rv  api_key_for_prober  r   rw  curatedr  mdev_modelsry  rk  seenmergedr!   r   r{   r   r   r   s1                                                    r   _model_flow_api_key_providerr  &
  sz   /     ,G-4-E-Eg&&q)2G++1rL L&& $R(=BIIb",=
 *;L%  h<	%E (120<|," .99\/R4.-- 
 %\:>Dv~B ; 2 ,-: 9 < BCv~./
 KLG L$\2Qbiib6Q	""7+1rB266*%+,224::<K"266*#5#;<BBD "?W%?%?Ne
 +>:;.8\<5$	z.)9=>DDFH &&'>?c |X6!) j -;(Ww]7-CTV	.)NJ HS_--EFG		&?(Ww]7-CTV
 /%#


 HS_--HIJ		 6(Ww]7-CTV"&&{B7&'8.I$JHS_-_W\\N$OP "K@1+> +67a	77!+.
  ,Awwy,"))!,+, Z 11STU$
$S_$55rs #&&{B7 	<-k:K  +67a	77k*  ,Awwy,a(+, $
(
HS_--OPQW* JS_--jk !- !*1g&r  ++<nMKs;/3w<?(
Z 1dST$
$S_$55rs
 55EO
>A'S9

 
 4KO$--'Iz'IIJ
 	B.{;ArG +'(+(
	^,224H 992;IH8$ m %&*/Y&RE CL'j*j(uE99 7X NE*IIj$'C&xjw||nAFGlU  	% $	%@  		  "8, 	GH	8  	6se<=WXJ	H   8,  		 8B
"  	G	 "8, 	H	s   .\ B\1 ] 7
]# ^ ^!^& ,^6!^;&_  _ \.-\.1	\>=\>] ] #^(^		^	^^&	^32^3 ___'&_'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	}d}|r |      r|sd	}t'        |      xr | xs |}| }|r|rkdd
lm} ddlm} d}|d   j.                  D ]6  }t1        j2                  |d      j5                         |k(  s+ ||      }|s6 n t7        d|dd  d|        n|rt7        d       t7                t9        d      }|dk(  rd	}n|dk(  ry|rt7                t7        d       t7                t7        d       t7        d       t7        d       t7                	 t;        d      j5                         }|dk(  r	 ||      sry|dk(  r`t7                t7        d       t7                ddl m!} 	  |d      j5                         }|st7        d        y |	||!       t7        d"       nt7        d#       yt7                |
jE                  dg       }|r |||d$      }n	 t;        d%      j5                         }|r~ ||        |       }|jE                  d&      }tG        |tH              s|rd'|ini }||d&<   d|d(<   |jK                  d)d       tM        |        ||        |        t7        d*| d+       yt7        d,       y# t$        $ r Y w xY w# t<        t>        f$ r t7                Y yw xY w# t<        t>        f$ r t7                Y yw xY w# t<        t>        f$ r d}Y w xY w)-uR   Flow for Anthropic provider — OAuth subscription, API key, or Claude Code creds.r   )_run_anthropic_oauth_flowr&  )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: Nr(  r)  u.     Claude Code credentials: ✓ (auto-detected)zAnthropic credentials:rN   rO   r9  z0    1. Claude Pro/Max subscription (OAuth login)z(    2. Anthropic API key (pay-per-token)r  rU   rV   rW   z>  Get an API key at: https://platform.claude.com/settings/keysr:  z  API key (sk-ant-...): r  )save_fnr*  r/  )r   r   z-Model name (e.g., claude-sonnet-4-20250514): r   r   r   r?   r   z (via Anthropic)r   )'r   r  r6   rm   rn   ro   r   r   r   r   r  r   r  r  agent.anthropic_adapterr  r  r  r>   r   r  r  r   rw   r  r  r]   rZ   rg   r\   r^   r_   r[  r;  r<   r7   r8   r   r   ) r   r   r  rm   rn   ro   r   r   r   r  r  r  r   cc_availabler  r  r  cc_credsexisting_is_stale_oauth	has_creds
needs_authr  r   r1  varrf   r;  rs   r  r   r   r   s                                    r   _model_flow_anthropicr  `  sM   9 
  3 2$&LL	
 	
 0128<L $5l"&l#C,C(CTIJI9 M(5FF 99S"%++-=$?$DM$	
 +L",=+>gm_U BC01IJXJx /0@A89o	/0668F
 S=,^<s]GRSGE./IJPPR n%"7NC() .!	G "%%k26J*'(
	LMSSUH 8$ m %&*/Y&RE CL'j		*d#(/C&xj0@ABlm  l "8, 	G	  &x0 2 "8, 	H	sG   K #K 5K: &L 	KKK76K7:LLL-,L-)r   r:   rL  r:   )r'   r:   r   r:   rL  r   )r?   r:   r+   r:   rL  None)r`   r:   rL  r:   )r   )ru   r:   r   r8   rL  r  )r   N)r  r:   rL  r:   )"__doc__
__future__r   r   r  r  r   r   r&   r   r)   rH   rg   r   r   r   r  r  r#  r/  r5  rp  r  r  r  r  r  r$  r3  rX  rd  rl  r  r  rF  r   r   <module>r     s   ( #  	  > 
". 22 2 
	2j#LAHFR-j_BVpOT Ob.`35l]@n`~/@ENsDj[zpd^@K\eN7,txt	Ur   