hermes-agent-features/hermes_cli
Teknium 2c6bbaf352
fix(gateway): coerce scalar model: to dict before /model --global persist (#32272)
Reported via AskClaw. When config.yaml has `model: <name>` (flat string)
instead of the nested `model: {default: ..., provider: ...}` form, every
gateway `/model X --global` crashed silently with

    TypeError: 'str' object does not support item assignment

The persist block did:

    model_cfg = cfg.setdefault("model", {})
    model_cfg["default"] = result.new_model

`setdefault` returns the existing scalar, and the next assignment blows
up. The 'switch failed' warning was logged at WARNING level and the user
never saw why their persist didn't stick.

Coerce scalar/None `model:` into a dict before mutation, in both the
gateway path (`gateway/run.py`) and the sister site in
`hermes_cli/doctor.py --fix` (same setdefault-on-string flaw). The CLI
`/model` path is unaffected because it goes through `_set_nested` which
already replaces scalar leaves with dicts.

Regression test `tests/gateway/test_model_command_flat_string_config.py`
covers the flat-string, missing, and proper-dict cases. Without the fix,
the flat-string case fails with the exact original TypeError.
2026-05-25 15:22:23 -07:00
..
proxy
__init__.py
_parser.py
_subprocess_compat.py
auth_commands.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
auth.py feat(providers): add OpenAI API provider option 2026-05-25 00:59:53 -07:00
azure_detect.py
backup.py fix(backup): skip symlinked files in zip archives (#25289) 2026-05-25 05:07:52 -07:00
banner.py
browser_connect.py
bundles.py
callbacks.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
checkpoints.py
claw.py
cli_output.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
clipboard.py
codex_models.py
codex_runtime_plugin_migration.py
codex_runtime_switch.py
colors.py
commands.py
completion.py
config.py fix(dashboard): suffix-allowlist plugin assets + denylist subprocess-influencing env vars (#32277) 2026-05-25 15:07:19 -07:00
container_boot.py fix(docker): make s6 lifecycle work for the unprivileged hermes user 2026-05-25 12:23:23 +10:00
copilot_auth.py
cron.py
curator.py
curses_ui.py
debug.py
default_soul.py
dep_ensure.py
dingtalk_auth.py
doctor.py fix(gateway): coerce scalar model: to dict before /model --global persist (#32272) 2026-05-25 15:22:23 -07:00
dump.py
env_loader.py fix(secrets): only apply external secrets once per HERMES_HOME per process (#32271) 2026-05-25 15:18:55 -07:00
fallback_cmd.py
fallback_config.py
gateway_windows.py
gateway.py Merge pull request #31760 from NousResearch/hermes/hermes-bf5898da 2026-05-25 12:57:51 +10:00
goals.py
hooks.py
inventory.py
kanban_db.py fix(kanban): scratch tasks must not inherit board.default_workdir (#28818) 2026-05-24 15:48:58 -07:00
kanban_decompose.py
kanban_diagnostics.py
kanban_specify.py
kanban_swarm.py
kanban.py
logs.py
main.py fix(update): reject symlink members in update ZIP 2026-05-25 05:15:55 -07:00
mcp_config.py
memory_setup.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
migrate.py
model_catalog.py
model_normalize.py
model_switch.py
models.py feat(providers): extend openai-api with live /v1/models fetch + gpt-5.5-pro 2026-05-25 00:59:53 -07:00
nous_subscription.py
oneshot.py
pairing.py
platforms.py
plugins_cmd.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
plugins.py feat(stt): add register_transcription_provider() plugin hook 2026-05-25 01:41:19 -07:00
portal_cli.py
profile_describer.py
profile_distribution.py fix(profile): reject symlinks in distributions (#25292) 2026-05-25 05:07:58 -07:00
profiles.py fix(security): tighten .env file permissions to 0600 at all creation sites 2026-05-25 03:40:47 -07:00
providers.py feat(providers): add OpenAI API provider option 2026-05-25 00:59:53 -07:00
pt_input_extras.py
pty_bridge.py
relaunch.py
runtime_provider.py
secret_prompt.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
secrets_cli.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
security_advisories.py
security_audit.py
send_cmd.py
service_manager.py fix(docker): make s6 lifecycle work for the unprivileged hermes user 2026-05-25 12:23:23 +10:00
session_recap.py
setup.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
skills_config.py
skills_hub.py fix: harden skill trust source matching (#31229) 2026-05-25 01:51:15 -07:00
skin_engine.py
slack_cli.py
status.py
stdio.py
timeouts.py
tips.py
tools_config.py fix(model): include Premium+ in xAI OAuth label 2026-05-24 18:12:16 -07:00
uninstall.py
vercel_auth.py
voice.py
web_server.py fix(dashboard): suffix-allowlist plugin assets + denylist subprocess-influencing env vars (#32277) 2026-05-25 15:07:19 -07:00
webhook.py
xai_retirement.py