fix(hermes): «конфигурация не найдена» при работающем Hermes

Проверялся ровно один путь — $HERMES_HOME/config.yaml. Hermes хранит
конфигурацию по-разному в зависимости от версии и способа установки, и у
владельца на Linux хаб писал «В Hermes: конфигурация не найдена» при
работающем Hermes v0.20.6.

Теперь проверяются семь известных мест, и в сообщении перечисляется, где
именно искали, — владелец видит список и может назвать верный путь.

Отдельно различаются «файла нет» и «нет доступа к каталогу»: закрытый
правами каталог помечается как непроверенный, а не как отсутствующий.
Это тот же класс ошибки, на котором я сам дважды ошибся в диагнозе,
приняв отказ в доступе за отсутствие файла.

599 passed, ruff clean, релизный гейт 10/10.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hermes Team 2026-08-31 23:22:08 +07:00
parent e74d4fbe4a
commit 26f7d2ce73

View file

@ -277,8 +277,46 @@ def setup_memory_structure(
def get_hermes_config_status(config_path: Optional[Path] = None) -> Dict[str, Any]:
"""Read Hermes configuration (~/.hermes/config.yaml) in read-only mode to provide status feedback."""
import yaml
checked: list = []
if config_path is None:
config_path = get_hermes_home() / "config.yaml"
# Hermes хранит конфигурацию не в одном месте: путь зависит от версии и
# способа установки. Раньше проверялся ровно один файл, и у владельца на
# Linux хаб писал «конфигурация не найдена» при работающем Hermes.
home = get_hermes_home()
candidates = [
home / "config.yaml",
home / "config.yml",
home / "config.json",
home / "hermes-agent" / "config.yaml",
Path.home() / ".hermes" / "config.yaml",
Path.home() / ".config" / "hermes" / "config.yaml",
Path.home() / ".config" / "hermes-agent" / "config.yaml",
]
seen = set()
for candidate in candidates:
key = str(candidate)
if key in seen:
continue
seen.add(key)
checked.append(key)
try:
if candidate.exists():
config_path = candidate
break
except OSError as exc:
# Каталог может быть закрыт правами: это «не смогли проверить»,
# а не «файла нет». Разница важна, иначе диагноз ложный.
checked[-1] = f"{key} (нет доступа: {exc.strerror or exc})"
else:
return {
"exists": False,
"model": None,
"provider": None,
"base_url": None,
"path": None,
"checked_paths": checked,
"message": "Конфигурация Hermes не найдена. Проверено: " + "; ".join(checked),
}
if not config_path.exists():
return {
@ -287,7 +325,8 @@ def get_hermes_config_status(config_path: Optional[Path] = None) -> Dict[str, An
"provider": None,
"base_url": None,
"path": str(config_path),
"message": "Конфигурационный файл ~/.hermes/config.yaml не найден",
"checked_paths": checked or [str(config_path)],
"message": f"Конфигурация Hermes не найдена по пути {config_path}",
}
try: