Files
hermes-agent/hermes_cli/config_check_diagnostics.py
kshitijk4poor 361dc5cf69 fix(cli): judge saved selections the way the runtime does in config check
Follow-up to the config check diagnostics from #127392.

- Saved platform_toolsets are validated by one resolver,
  toolset_validation.saved_toolset_resolver, shared with
  `hermes config migrate`. The two commands previously disagreed: migrate
  flagged MCP server names and plugin-platform bundles (even suggesting
  'hermes-teams' for 'hermes-teams'), while config check accepted them.
- A configured MCP server is known even when disabled (enabled: false);
  it is inactive, not a typo.
- known_plugin_toolsets is no longer treated as proof that a toolset
  exists. It records what a platform was offered at save time, so it hid
  toolsets of uninstalled plugins, the stale case this check is for.
- Plugin-provided names are consulted only for names nothing else
  explains, so a clean config no longer runs plugin discovery.
- A malformed mcp_servers (a list) no longer crashes the command.
- The top-level `toolsets` check is dropped: the CLI resolves its
  toolsets from --toolsets or platform_toolsets, and reads the top-level
  key only for the legacy kanban opt-in.
- Disabled platforms are read with the runtime's plugins.disabled reader,
  so a non-list value (which the runtime ignores) is no longer reported
  as disabling a platform. Required credentials come from
  _platform_manifest_env_entries, which now takes optional=False.
- Tests use a synthetic platform manifest instead of the real Telegram
  one, and assert config check and migrate report the same names.
2026-09-29 20:34:45 +05:30

35 lines
1.7 KiB
Python

"""Read-only diagnostics for saved toolsets and bundled platform selections."""
from __future__ import annotations
from collections.abc import Callable
from typing import Any
def config_check_diagnostics(config: dict[str, Any], get_env_value: Callable[[str], str | None]) -> list[str]:
"""Report saved selections that would otherwise be lost in startup output.
Toolset names are judged by the resolver ``hermes config migrate`` also uses, disabled platforms
by the runtime's own ``plugins.disabled`` reader and the manifest-name gate of
``plugins_discovery.gate_manifest``. A configured credential is only a reason to *mention* a
disabled platform; disabling it may have been intentional.
"""
from hermes_cli.config import _platform_manifest_env_entries, _platform_plugin_manifests
from hermes_cli.plugins_discovery import _get_disabled_plugins
from hermes_cli.toolset_validation import saved_toolset_resolver, validate_platform_toolsets
diagnostics = validate_platform_toolsets(config.get("platform_toolsets"), saved_toolset_resolver(config))
disabled = _get_disabled_plugins()
for name, manifest in _platform_plugin_manifests(source="bundled"):
key = f"platforms/{name}"
if not {key, str(manifest.get("name"))} & disabled:
continue
required = [env for env, _secret, _meta in _platform_manifest_env_entries(manifest, optional=False)]
if required and all(get_env_value(env) for env in required):
diagnostics.append(
f"platform plugin '{key}' is disabled while its required credentials are configured. "
f"Run `hermes plugins enable {key}` if you want it active."
)
return diagnostics