mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
fix(auth): refresh Nous entitlement in tool menus
This commit is contained in:
parent
406901b27d
commit
1cf5e639b3
8 changed files with 304 additions and 108 deletions
|
|
@ -228,6 +228,8 @@ def _resolve_browser_feature_state(
|
|||
|
||||
def get_nous_subscription_features(
|
||||
config: Optional[Dict[str, object]] = None,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> NousSubscriptionFeatures:
|
||||
if config is None:
|
||||
config = load_config() or {}
|
||||
|
|
@ -236,7 +238,10 @@ def get_nous_subscription_features(
|
|||
provider_is_nous = str(model_cfg.get("provider") or "").strip().lower() == "nous"
|
||||
|
||||
try:
|
||||
account_info = get_nous_portal_account_info()
|
||||
if force_fresh:
|
||||
account_info = get_nous_portal_account_info(force_fresh=True)
|
||||
else:
|
||||
account_info = get_nous_portal_account_info()
|
||||
except Exception:
|
||||
account_info = None
|
||||
|
||||
|
|
@ -322,6 +327,7 @@ def get_nous_subscription_features(
|
|||
modal_mode,
|
||||
has_direct=direct_modal,
|
||||
managed_ready=managed_modal_available,
|
||||
managed_enabled=managed_tools_flag,
|
||||
)
|
||||
|
||||
web_managed = web_backend == "firecrawl" and managed_web_available and not direct_firecrawl
|
||||
|
|
@ -499,11 +505,15 @@ def apply_nous_managed_defaults(
|
|||
config: Dict[str, object],
|
||||
*,
|
||||
enabled_toolsets: Optional[Iterable[str]] = None,
|
||||
force_fresh: bool = False,
|
||||
) -> set[str]:
|
||||
if not managed_nous_tools_enabled():
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
if not (
|
||||
features.account_info
|
||||
and features.account_info.logged_in
|
||||
and features.account_info.paid_service_access is True
|
||||
):
|
||||
return set()
|
||||
|
||||
features = get_nous_subscription_features(config)
|
||||
if not features.provider_is_nous:
|
||||
return set()
|
||||
|
||||
|
|
@ -600,6 +610,8 @@ _ALL_GATEWAY_KEYS = ("web", "image_gen", "tts", "browser")
|
|||
|
||||
def get_gateway_eligible_tools(
|
||||
config: Optional[Dict[str, object]] = None,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> tuple[list[str], list[str], list[str]]:
|
||||
"""Return (unconfigured, has_direct, already_managed) tool key lists.
|
||||
|
||||
|
|
@ -610,7 +622,11 @@ def get_gateway_eligible_tools(
|
|||
All lists are empty when the user is not a paid Nous subscriber or
|
||||
is not using Nous as their provider.
|
||||
"""
|
||||
if not managed_nous_tools_enabled():
|
||||
if force_fresh:
|
||||
managed_enabled = managed_nous_tools_enabled(force_fresh=True)
|
||||
else:
|
||||
managed_enabled = managed_nous_tools_enabled()
|
||||
if not managed_enabled:
|
||||
return [], [], []
|
||||
|
||||
if config is None:
|
||||
|
|
@ -701,7 +717,11 @@ def apply_gateway_defaults(
|
|||
return changed
|
||||
|
||||
|
||||
def prompt_enable_tool_gateway(config: Dict[str, object]) -> set[str]:
|
||||
def prompt_enable_tool_gateway(
|
||||
config: Dict[str, object],
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
) -> set[str]:
|
||||
"""If eligible tools exist, prompt the user to enable the Tool Gateway.
|
||||
|
||||
Uses prompt_choice() with a description parameter so the curses TUI
|
||||
|
|
@ -710,7 +730,10 @@ def prompt_enable_tool_gateway(config: Dict[str, object]) -> set[str]:
|
|||
Returns the set of tools that were enabled, or empty set if the user
|
||||
declined or no tools were eligible.
|
||||
"""
|
||||
unconfigured, has_direct, already_managed = get_gateway_eligible_tools(config)
|
||||
unconfigured, has_direct, already_managed = get_gateway_eligible_tools(
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
if not unconfigured and not has_direct:
|
||||
return set()
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from hermes_cli.nous_subscription import (
|
|||
get_nous_subscription_features,
|
||||
)
|
||||
from hermes_cli.nous_account import format_nous_portal_entitlement_message
|
||||
from tools.tool_backend_helpers import fal_key_is_configured, managed_nous_tools_enabled
|
||||
from tools.tool_backend_helpers import fal_key_is_configured
|
||||
from utils import base_url_hostname, is_truthy_value
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -1400,7 +1400,12 @@ def _save_platform_tools(config: dict, platform: str, enabled_toolset_keys: Set[
|
|||
save_config(config)
|
||||
|
||||
|
||||
def _toolset_has_keys(ts_key: str, config: dict = None) -> bool:
|
||||
def _toolset_has_keys(
|
||||
ts_key: str,
|
||||
config: dict = None,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> bool:
|
||||
"""Check if a toolset's required API keys are configured."""
|
||||
if config is None:
|
||||
config = load_config()
|
||||
|
|
@ -1415,7 +1420,7 @@ def _toolset_has_keys(ts_key: str, config: dict = None) -> bool:
|
|||
return False
|
||||
|
||||
if ts_key in {"web", "image_gen", "tts", "browser"}:
|
||||
features = get_nous_subscription_features(config)
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
feature = features.features.get(ts_key)
|
||||
if feature and (feature.available or feature.managed_by_nous):
|
||||
return True
|
||||
|
|
@ -1423,7 +1428,7 @@ def _toolset_has_keys(ts_key: str, config: dict = None) -> bool:
|
|||
# Check TOOL_CATEGORIES first (provider-aware)
|
||||
cat = TOOL_CATEGORIES.get(ts_key)
|
||||
if cat:
|
||||
for provider in _visible_providers(cat, config):
|
||||
for provider in _visible_providers(cat, config, force_fresh=force_fresh):
|
||||
env_vars = provider.get("env_vars", [])
|
||||
if not env_vars:
|
||||
return True # No-key provider (e.g. Local Browser, Edge TTS)
|
||||
|
|
@ -1494,7 +1499,13 @@ def _estimate_tool_tokens() -> Dict[str, int]:
|
|||
return _tool_token_cache
|
||||
|
||||
|
||||
def _prompt_toolset_checklist(platform_label: str, enabled: Set[str], platform: str = "cli") -> Set[str]:
|
||||
def _prompt_toolset_checklist(
|
||||
platform_label: str,
|
||||
enabled: Set[str],
|
||||
platform: str = "cli",
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
) -> Set[str]:
|
||||
"""Multi-select checklist of toolsets. Returns set of selected toolset keys."""
|
||||
from hermes_cli.curses_ui import curses_checklist
|
||||
from toolsets import resolve_toolset
|
||||
|
|
@ -1512,7 +1523,10 @@ def _prompt_toolset_checklist(platform_label: str, enabled: Set[str], platform:
|
|||
labels = []
|
||||
for ts_key, ts_label, ts_desc in effective:
|
||||
suffix = ""
|
||||
if not _toolset_has_keys(ts_key) and (TOOL_CATEGORIES.get(ts_key) or TOOLSET_ENV_REQUIREMENTS.get(ts_key)):
|
||||
if (
|
||||
not _toolset_has_keys(ts_key, force_fresh=force_fresh)
|
||||
and (TOOL_CATEGORIES.get(ts_key) or TOOLSET_ENV_REQUIREMENTS.get(ts_key))
|
||||
):
|
||||
suffix = " [no API key]"
|
||||
labels.append(f"{ts_label} ({ts_desc}){suffix}")
|
||||
|
||||
|
|
@ -1548,7 +1562,12 @@ def _prompt_toolset_checklist(platform_label: str, enabled: Set[str], platform:
|
|||
|
||||
# ─── Provider-Aware Configuration ────────────────────────────────────────────
|
||||
|
||||
def _configure_toolset(ts_key: str, config: dict):
|
||||
def _configure_toolset(
|
||||
ts_key: str,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Configure a toolset - provider selection + API keys.
|
||||
|
||||
Uses TOOL_CATEGORIES for provider-aware config, falls back to simple
|
||||
|
|
@ -1557,7 +1576,7 @@ def _configure_toolset(ts_key: str, config: dict):
|
|||
cat = TOOL_CATEGORIES.get(ts_key)
|
||||
|
||||
if cat:
|
||||
_configure_tool_category(ts_key, cat, config)
|
||||
_configure_tool_category(ts_key, cat, config, force_fresh=force_fresh)
|
||||
else:
|
||||
# Simple fallback for vision, moa, etc.
|
||||
_configure_simple_requirements(ts_key)
|
||||
|
|
@ -1810,12 +1829,22 @@ def _plugin_tts_providers() -> list[dict]:
|
|||
return rows
|
||||
|
||||
|
||||
def _visible_providers(cat: dict, config: dict) -> list[dict]:
|
||||
def _visible_providers(
|
||||
cat: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> list[dict]:
|
||||
"""Return provider entries visible for the current auth/config state."""
|
||||
features = get_nous_subscription_features(config)
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
managed_available = bool(
|
||||
features.account_info
|
||||
and features.account_info.logged_in
|
||||
and features.account_info.paid_service_access is True
|
||||
)
|
||||
visible = []
|
||||
for provider in cat.get("providers", []):
|
||||
if provider.get("managed_nous_feature") and not managed_nous_tools_enabled():
|
||||
if provider.get("managed_nous_feature") and not managed_available:
|
||||
continue
|
||||
if provider.get("requires_nous_auth") and not features.nous_auth_present:
|
||||
continue
|
||||
|
|
@ -1856,13 +1885,24 @@ def _visible_providers(cat: dict, config: dict) -> list[dict]:
|
|||
return visible
|
||||
|
||||
|
||||
def _hidden_nous_gateway_message(cat: dict, config: dict, capability: str) -> str:
|
||||
def _hidden_nous_gateway_message(
|
||||
cat: dict,
|
||||
config: dict,
|
||||
capability: str,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> str:
|
||||
"""Return a reason when a category's Nous provider is hidden."""
|
||||
if managed_nous_tools_enabled():
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
managed_available = bool(
|
||||
features.account_info
|
||||
and features.account_info.logged_in
|
||||
and features.account_info.paid_service_access is True
|
||||
)
|
||||
if managed_available:
|
||||
return ""
|
||||
if not any(p.get("managed_nous_feature") for p in cat.get("providers", [])):
|
||||
return ""
|
||||
features = get_nous_subscription_features(config)
|
||||
message = format_nous_portal_entitlement_message(
|
||||
features.account_info,
|
||||
capability=capability,
|
||||
|
|
@ -1901,17 +1941,22 @@ def _post_setup_already_installed(post_setup_key: str) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def _toolset_needs_configuration_prompt(ts_key: str, config: dict) -> bool:
|
||||
def _toolset_needs_configuration_prompt(
|
||||
ts_key: str,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> bool:
|
||||
"""Return True when enabling this toolset should open provider setup."""
|
||||
cat = TOOL_CATEGORIES.get(ts_key)
|
||||
if not cat:
|
||||
return not _toolset_has_keys(ts_key, config)
|
||||
return not _toolset_has_keys(ts_key, config, force_fresh=force_fresh)
|
||||
|
||||
# If any visible provider has a registered post_setup install-state
|
||||
# check that hasn't been satisfied (e.g. cua-driver binary not on
|
||||
# PATH yet), force the configuration flow so `_configure_provider`
|
||||
# invokes `_run_post_setup` and the install actually runs.
|
||||
for provider in _visible_providers(cat, config):
|
||||
for provider in _visible_providers(cat, config, force_fresh=force_fresh):
|
||||
post_setup = provider.get("post_setup")
|
||||
if post_setup and not _post_setup_already_installed(post_setup):
|
||||
return True
|
||||
|
|
@ -1962,18 +2007,25 @@ def _toolset_needs_configuration_prompt(ts_key: str, config: dict) -> bool:
|
|||
pass
|
||||
return True
|
||||
|
||||
return not _toolset_has_keys(ts_key, config)
|
||||
return not _toolset_has_keys(ts_key, config, force_fresh=force_fresh)
|
||||
|
||||
|
||||
def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
||||
def _configure_tool_category(
|
||||
ts_key: str,
|
||||
cat: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Configure a tool category with provider selection."""
|
||||
icon = cat.get("icon", "")
|
||||
name = cat["name"]
|
||||
providers = _visible_providers(cat, config)
|
||||
providers = _visible_providers(cat, config, force_fresh=force_fresh)
|
||||
hidden_nous_message = _hidden_nous_gateway_message(
|
||||
cat,
|
||||
config,
|
||||
f"the Nous Subscription provider for {name}",
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
|
||||
# Check Python version requirement
|
||||
|
|
@ -1998,7 +2050,7 @@ def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
|||
if hidden_nous_message:
|
||||
for line in hidden_nous_message.splitlines():
|
||||
_print_warning(f" {line}")
|
||||
_configure_provider(provider, config)
|
||||
_configure_provider(provider, config, force_fresh=force_fresh)
|
||||
else:
|
||||
# Multiple providers - let user choose
|
||||
print()
|
||||
|
|
@ -2018,7 +2070,10 @@ def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
|||
# obvious which options cost extra vs. cost nothing on top of Nous.
|
||||
try:
|
||||
_nous_logged_in = bool(
|
||||
get_nous_subscription_features(config).nous_auth_present
|
||||
get_nous_subscription_features(
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
).nous_auth_present
|
||||
)
|
||||
except Exception:
|
||||
_nous_logged_in = False
|
||||
|
|
@ -2030,7 +2085,7 @@ def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
|||
configured = ""
|
||||
env_vars = p.get("env_vars", [])
|
||||
if not env_vars or all(get_env_value(v["key"]) for v in env_vars):
|
||||
if _is_provider_active(p, config):
|
||||
if _is_provider_active(p, config, force_fresh=force_fresh):
|
||||
configured = " [active]"
|
||||
elif not env_vars:
|
||||
configured = ""
|
||||
|
|
@ -2050,7 +2105,11 @@ def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
|||
provider_choices.append("Skip — keep defaults / configure later")
|
||||
|
||||
# Detect current provider as default
|
||||
default_idx = _detect_active_provider_index(providers, config)
|
||||
default_idx = _detect_active_provider_index(
|
||||
providers,
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
|
||||
provider_idx = _prompt_choice(f" {title}:", provider_choices, default_idx)
|
||||
|
||||
|
|
@ -2059,10 +2118,15 @@ def _configure_tool_category(ts_key: str, cat: dict, config: dict):
|
|||
_print_info(f" Skipped {name}")
|
||||
return
|
||||
|
||||
_configure_provider(providers[provider_idx], config)
|
||||
_configure_provider(providers[provider_idx], config, force_fresh=force_fresh)
|
||||
|
||||
|
||||
def _is_provider_active(provider: dict, config: dict) -> bool:
|
||||
def _is_provider_active(
|
||||
provider: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> bool:
|
||||
"""Check if a provider entry matches the currently active config."""
|
||||
plugin_name = provider.get("image_gen_plugin_name")
|
||||
if plugin_name:
|
||||
|
|
@ -2076,7 +2140,7 @@ def _is_provider_active(provider: dict, config: dict) -> bool:
|
|||
|
||||
managed_feature = provider.get("managed_nous_feature")
|
||||
if managed_feature:
|
||||
features = get_nous_subscription_features(config)
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
feature = features.features.get(managed_feature)
|
||||
if feature is None:
|
||||
return False
|
||||
|
|
@ -2123,10 +2187,15 @@ def _is_provider_active(provider: dict, config: dict) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def _detect_active_provider_index(providers: list, config: dict) -> int:
|
||||
def _detect_active_provider_index(
|
||||
providers: list,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = False,
|
||||
) -> int:
|
||||
"""Return the index of the currently active provider, or 0."""
|
||||
for i, p in enumerate(providers):
|
||||
if _is_provider_active(p, config):
|
||||
if _is_provider_active(p, config, force_fresh=force_fresh):
|
||||
return i
|
||||
# Fallback: env vars present → likely configured
|
||||
env_vars = p.get("env_vars", [])
|
||||
|
|
@ -2429,13 +2498,18 @@ def _select_plugin_video_gen_provider(plugin_name: str, config: dict) -> None:
|
|||
_configure_videogen_model_for_plugin(plugin_name, config)
|
||||
|
||||
|
||||
def _configure_provider(provider: dict, config: dict):
|
||||
def _configure_provider(
|
||||
provider: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Configure a single provider - prompt for API keys and set config."""
|
||||
env_vars = provider.get("env_vars", [])
|
||||
managed_feature = provider.get("managed_nous_feature")
|
||||
|
||||
if provider.get("requires_nous_auth"):
|
||||
features = get_nous_subscription_features(config)
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
entitled = bool(
|
||||
features.account_info and features.account_info.paid_service_access is True
|
||||
)
|
||||
|
|
@ -2536,7 +2610,10 @@ def _configure_provider(provider: dict, config: dict):
|
|||
_has_managed_sibling = True
|
||||
break
|
||||
if _has_managed_sibling:
|
||||
_features = get_nous_subscription_features(config)
|
||||
_features = get_nous_subscription_features(
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
_show_portal_hint = not _features.nous_auth_present
|
||||
except Exception:
|
||||
_show_portal_hint = False
|
||||
|
|
@ -2654,7 +2731,11 @@ def _configure_simple_requirements(ts_key: str):
|
|||
_print_warning(" Skipped")
|
||||
|
||||
|
||||
def _reconfigure_tool(config: dict):
|
||||
def _reconfigure_tool(
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Let user reconfigure an existing tool's provider or API key."""
|
||||
# Build list of configurable tools that are currently set up
|
||||
configurable = []
|
||||
|
|
@ -2662,7 +2743,10 @@ def _reconfigure_tool(config: dict):
|
|||
cat = TOOL_CATEGORIES.get(ts_key)
|
||||
reqs = TOOLSET_ENV_REQUIREMENTS.get(ts_key)
|
||||
if cat or reqs:
|
||||
if _toolset_has_keys(ts_key, config) or _toolset_enabled_for_reconfigure(ts_key, config):
|
||||
if (
|
||||
_toolset_has_keys(ts_key, config, force_fresh=force_fresh)
|
||||
or _toolset_enabled_for_reconfigure(ts_key, config)
|
||||
):
|
||||
configurable.append((ts_key, ts_label))
|
||||
|
||||
if not configurable:
|
||||
|
|
@ -2681,7 +2765,12 @@ def _reconfigure_tool(config: dict):
|
|||
cat = TOOL_CATEGORIES.get(ts_key)
|
||||
|
||||
if cat:
|
||||
_configure_tool_category_for_reconfig(ts_key, cat, config)
|
||||
_configure_tool_category_for_reconfig(
|
||||
ts_key,
|
||||
cat,
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
else:
|
||||
_reconfigure_simple_requirements(ts_key)
|
||||
|
||||
|
|
@ -2710,15 +2799,22 @@ def _toolset_enabled_for_reconfigure(ts_key: str, config: dict) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def _configure_tool_category_for_reconfig(ts_key: str, cat: dict, config: dict):
|
||||
def _configure_tool_category_for_reconfig(
|
||||
ts_key: str,
|
||||
cat: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Reconfigure a tool category - provider selection + API key update."""
|
||||
icon = cat.get("icon", "")
|
||||
name = cat["name"]
|
||||
providers = _visible_providers(cat, config)
|
||||
providers = _visible_providers(cat, config, force_fresh=force_fresh)
|
||||
hidden_nous_message = _hidden_nous_gateway_message(
|
||||
cat,
|
||||
config,
|
||||
f"the Nous Subscription provider for {name}",
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
|
||||
if len(providers) == 1:
|
||||
|
|
@ -2728,7 +2824,7 @@ def _configure_tool_category_for_reconfig(ts_key: str, cat: dict, config: dict):
|
|||
if hidden_nous_message:
|
||||
for line in hidden_nous_message.splitlines():
|
||||
_print_warning(f" {line}")
|
||||
_reconfigure_provider(provider, config)
|
||||
_reconfigure_provider(provider, config, force_fresh=force_fresh)
|
||||
else:
|
||||
print()
|
||||
print(color(f" --- {icon} {name} - Choose a provider ---", Colors.CYAN))
|
||||
|
|
@ -2744,7 +2840,7 @@ def _configure_tool_category_for_reconfig(ts_key: str, cat: dict, config: dict):
|
|||
configured = ""
|
||||
env_vars = p.get("env_vars", [])
|
||||
if not env_vars or all(get_env_value(v["key"]) for v in env_vars):
|
||||
if _is_provider_active(p, config):
|
||||
if _is_provider_active(p, config, force_fresh=force_fresh):
|
||||
configured = " [active]"
|
||||
elif not env_vars:
|
||||
configured = ""
|
||||
|
|
@ -2752,19 +2848,32 @@ def _configure_tool_category_for_reconfig(ts_key: str, cat: dict, config: dict):
|
|||
configured = " [configured]"
|
||||
provider_choices.append(f"{p['name']}{badge}{tag}{configured}")
|
||||
|
||||
default_idx = _detect_active_provider_index(providers, config)
|
||||
default_idx = _detect_active_provider_index(
|
||||
providers,
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
|
||||
provider_idx = _prompt_choice(" Select provider:", provider_choices, default_idx)
|
||||
_reconfigure_provider(providers[provider_idx], config)
|
||||
_reconfigure_provider(
|
||||
providers[provider_idx],
|
||||
config,
|
||||
force_fresh=force_fresh,
|
||||
)
|
||||
|
||||
|
||||
def _reconfigure_provider(provider: dict, config: dict):
|
||||
def _reconfigure_provider(
|
||||
provider: dict,
|
||||
config: dict,
|
||||
*,
|
||||
force_fresh: bool = True,
|
||||
):
|
||||
"""Reconfigure a provider - update API keys."""
|
||||
env_vars = provider.get("env_vars", [])
|
||||
managed_feature = provider.get("managed_nous_feature")
|
||||
|
||||
if provider.get("requires_nous_auth"):
|
||||
features = get_nous_subscription_features(config)
|
||||
features = get_nous_subscription_features(config, force_fresh=force_fresh)
|
||||
entitled = bool(
|
||||
features.account_info and features.account_info.paid_service_access is True
|
||||
)
|
||||
|
|
@ -2976,11 +3085,11 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
auto_configured = apply_nous_managed_defaults(
|
||||
config,
|
||||
enabled_toolsets=new_enabled,
|
||||
force_fresh=True,
|
||||
)
|
||||
if managed_nous_tools_enabled():
|
||||
for ts_key in sorted(auto_configured):
|
||||
label = next((l for k, l, _ in CONFIGURABLE_TOOLSETS if k == ts_key), ts_key)
|
||||
print(color(f" ✓ {label}: using your Nous subscription defaults", Colors.GREEN))
|
||||
for ts_key in sorted(auto_configured):
|
||||
label = next((l for k, l, _ in CONFIGURABLE_TOOLSETS if k == ts_key), ts_key)
|
||||
print(color(f" ✓ {label}: using your Nous subscription defaults", Colors.GREEN))
|
||||
|
||||
# Walk through ALL selected tools that have provider options or
|
||||
# need API keys. This ensures browser (Local vs Browserbase),
|
||||
|
|
@ -3048,7 +3157,7 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
|
||||
# "Reconfigure" selected
|
||||
if idx == _reconfig_idx:
|
||||
_reconfigure_tool(config)
|
||||
_reconfigure_tool(config, force_fresh=True)
|
||||
print()
|
||||
continue
|
||||
|
||||
|
|
@ -3064,7 +3173,11 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
all_current = set()
|
||||
for pk in platform_keys:
|
||||
all_current |= _get_platform_tools(config, pk, include_default_mcp_servers=False)
|
||||
new_enabled = _prompt_toolset_checklist("All platforms", all_current)
|
||||
new_enabled = _prompt_toolset_checklist(
|
||||
"All platforms",
|
||||
all_current,
|
||||
force_fresh=True,
|
||||
)
|
||||
if new_enabled != all_current:
|
||||
for pk in platform_keys:
|
||||
prev = _get_platform_tools(config, pk, include_default_mcp_servers=False)
|
||||
|
|
@ -3082,7 +3195,11 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
# Configure API keys for newly enabled tools
|
||||
for ts_key in sorted(added):
|
||||
if (TOOL_CATEGORIES.get(ts_key) or TOOLSET_ENV_REQUIREMENTS.get(ts_key)):
|
||||
if _toolset_needs_configuration_prompt(ts_key, config):
|
||||
if _toolset_needs_configuration_prompt(
|
||||
ts_key,
|
||||
config,
|
||||
force_fresh=True,
|
||||
):
|
||||
_configure_toolset(ts_key, config)
|
||||
_save_platform_tools(config, pk, new_enabled)
|
||||
save_config(config)
|
||||
|
|
@ -3104,7 +3221,11 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
current_enabled = _get_platform_tools(config, pkey, include_default_mcp_servers=False)
|
||||
|
||||
# Show checklist
|
||||
new_enabled = _prompt_toolset_checklist(pinfo["label"], current_enabled)
|
||||
new_enabled = _prompt_toolset_checklist(
|
||||
pinfo["label"],
|
||||
current_enabled,
|
||||
force_fresh=True,
|
||||
)
|
||||
|
||||
if new_enabled != current_enabled:
|
||||
added = new_enabled - current_enabled
|
||||
|
|
@ -3122,7 +3243,11 @@ def tools_command(args=None, first_install: bool = False, config: dict = None):
|
|||
# Configure newly enabled toolsets that need API keys
|
||||
for ts_key in sorted(added):
|
||||
if (TOOL_CATEGORIES.get(ts_key) or TOOLSET_ENV_REQUIREMENTS.get(ts_key)):
|
||||
if _toolset_needs_configuration_prompt(ts_key, config):
|
||||
if _toolset_needs_configuration_prompt(
|
||||
ts_key,
|
||||
config,
|
||||
force_fresh=True,
|
||||
):
|
||||
_configure_toolset(ts_key, config)
|
||||
|
||||
_save_platform_tools(config, pkey, new_enabled)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue