The old flow blindly asked for an OpenRouter API key after ANY non-OR
provider selection, even for Nous Portal and Codex which already
support vision natively. This was confusing and annoying.
New behavior:
- OpenRouter: skip — vision uses Gemini via their OR key
- Nous Portal OAuth: skip — vision uses Gemini via Nous
- OpenAI Codex: skip — gpt-5.3-codex supports vision
- Custom endpoint (api.openai.com): show OpenAI vision model picker
(gpt-4o, gpt-4o-mini, gpt-4.1, etc.), saves AUXILIARY_VISION_MODEL
- Custom (other) / z.ai / kimi / minimax / nous-api:
- First checks if existing OR/Nous creds already cover vision
- If not, offers friendly choice: OpenRouter / OpenAI / Skip
- No more 'enter OpenRouter key' thrown in your face
Also fixes the setup summary to check actual vision availability
across all providers instead of hardcoding 'requires OPENROUTER_API_KEY'.
MoA still correctly requires OpenRouter (calls multiple frontier models).
Add a hands-on guide for using voice mode with Hermes, fix and expand the main voice-mode docs, surface /voice in messaging docs, and improve discoverability from the homepage and learning path.
Document the expanded skills hub functionality, including:
- skills.sh source usage
- well-known endpoint discovery
- check/update commands
- real install/inspect examples
- accurate --force semantics and trust policy behavior
Also verified the docs site with a successful Docusaurus production build.
Document the new global-only SOUL behavior, add a dedicated use guide, update personality/context/config docs, and fix docs language that still described cwd-local SOUL loading.
Prevent gateway.platforms.discord from crashing at import time when discord.py is unavailable. Python 3.11 eagerly evaluates annotations, so using discord.Interaction and similar annotations caused an AttributeError after the optional import fallback set discord=None. Add postponed annotation evaluation and a regression test covering import without discord installed.
Round out the skills hub integration with:
- richer skills.sh metadata and security surfacing during inspect/install
- generic check/update flows for hub-installed skills
- support for well-known Agent Skills endpoints via /.well-known/skills/index.json
Also persist upstream bundle metadata in the lock file and add
regression coverage plus live-compatible path handling for both
skills.sh aliases and well-known endpoints.
Seed ~/.hermes/SOUL.md when missing, load SOUL only from HERMES_HOME, and inject raw SOUL content without wrapper text. If the file exists but is empty, nothing is added to the system prompt.
* improve: add exc_info to MoA error logging
* refactor: tighten MoA traceback logging scope
Follow up on salvaged PR #998 by limiting exc_info logging to terminal
failure paths, avoiding duplicate aggregator errors, and refreshing the
MoA default OpenRouter model lineup to current frontier options.
---------
Co-authored-by: aydnOktay <xaydinoktay@gmail.com>
- store gateway PID metadata and validate the live process before trusting gateway.pid
- auto-refresh outdated systemd user units before start/restart so installs pick up --replace fixes
- sweep stray manual gateway processes after service stops
- add regression tests for PID validation and service drift recovery
Harden the skills.sh hub adapter by parsing skill detail pages when
search slugs do not map cleanly onto GitHub skill folder names.
This adds detail-page resolution for alias-style skills, improves
inspect metadata from the page itself, and covers the behavior with
regression tests plus live smoke validation for json-render-react.
Use getattr() when returning model metadata from GatewayRunner._run_agent so fake agents and minimal stubs without a model attribute do not break unrelated gateway flows while preserving the session-model backfill behavior.
Add regression coverage for backfilling NULL gateway session models in SQLite, preserving existing models, and forwarding the resolved agent model through SessionStore updates.
Gateway sessions end up with model=NULL because the session row is
created before AIAgent is constructed. After the agent responds,
update_session() writes token counts but never fills in the model.
Thread agent.model through _run_agent()'s return dict into
update_session() → update_token_counts(). The SQL uses
COALESCE(model, ?) so it only fills NULL rows — never overwrites
a model already set at creation time (e.g. CLI sessions).
If the agent falls back to a different provider, agent.model is
updated in-place by _try_activate_fallback(), so the recorded value
reflects whichever model actually produced the response.
Fixes#987
Expand the MCP feature docs with filtering and capability-aware registration details, add a practical 'Use MCP with Hermes' tutorial, add a config reference page, and wire the new docs into the sidebar and landing page.
Add regression coverage for the standalone email send path and pass an explicit default SSL context to STARTTLS for certificate verification, matching the gateway email adapter hardening salvaged from PR #994.
- initialize voice and interrupt runtime state in HermesCLI.__init__
- prevent chat -q from crashing before run() has executed
- add regression coverage for single-query state initialization
Tests were still mocking imap.search() and imap.fetch() but the
implementation was changed to use imap.uid("search", ...) and
imap.uid("fetch", ...) for proper UID-based IMAP operations.
- Use imap.uid() for search and fetch instead of imap.search/fetch.
Sequence numbers shift when messages are deleted, causing the adapter
to skip new messages or reprocess old ones. UIDs are stable.
- Pass ssl.create_default_context() to starttls() so the server
certificate is actually verified. Without it smtplib uses
ssl._create_stdlib_context() which skips verification.
Add a skills.sh-backed source adapter for the Hermes Skills Hub.
The new adapter uses skills.sh search results for discovery, falls back to
featured homepage links for browse-style queries, and resolves installs /
inspects through the underlying GitHub repo using common Agent Skills
layout conventions. Also expose skills-sh in CLI source filters and add
regression coverage for search, alias resolution, and source routing.
Extend the salvaged MCP filtering work so utility tools are also governed by policy and server capabilities. Store the registered tool subset per server so rediscovery and status reporting stay accurate after filtering.
The greedy `.*` captures with `re.DOTALL` cause `findall()` to merge
multiple tool calls into a single match — silently dropping all but the
last tool call. Switching to `.*?` (non-greedy) fixes extraction when
models return multiple tool calls in one response.
Adds test coverage for the DeepSeek V3 parser including a multi-tool
call regression test.
Co-authored-by: Himess <semihcvlk53@gmail.com>
Clarify that Parallel is an optional paid vendor workflow, add headless auth and context-chaining guidance, and align command examples more closely with upstream docs before salvaging PR #985.
- keep CLI voice prefixes API-local while storing the original user text
- persist explicit gateway off state and restore adapter auto-TTS suppression on restart
- add regression coverage for both behaviors
Add optional config keys under each mcp_servers entry:
- tools.include: whitelist, only listed tools are registered
- tools.exclude: blacklist, all tools except listed are registered
- enabled: false: skip server entirely, no connection attempt
Backward-compatible: no config keys = all tools registered as before.
Tests: TestMCPSelectiveToolLoading (4 tests), 134 passed total.
* fix(gateway): surface missing linger in status and doctor
Warn when a systemd user gateway service has linger disabled so users can
spot the common 'gateway sleeps after logout' deployment issue from both
hermes doctor and hermes gateway status.
* fix(gateway): check linger status after install
After installing the systemd user service, report whether linger is
already enabled instead of always printing the generic hint. This makes
post-install guidance match the user's actual deployment state.
Salvaged from PR #979 onto current main.
Preserve the current terminal backend checks while surfacing actionable
preflight errors for unknown TERMINAL_ENV values, missing SSH host/user
configuration, and missing Modal credentials/config. Tighten the modal
regression test so it deterministically exercises the config-missing
path.
Add a restore prompt for interactive updates, keep the stash when the user declines, and print a post-restore warning that local changes were reapplied on top of updated code.