fix: resolve 7 identified issues [automated]#17246
Open
Sldark23 wants to merge 93 commits into
Open
Conversation
…rmission issues (refs NousResearch#15865)
…ession metadata (refs NousResearch#15909)
…n job configuration (refs NousResearch#15890)
…context length detection (refs NousResearch#15882)
…to match user expectations (refs NousResearch#15843)
…ently skipping prompt (fixes NousResearch#16394)
… rendered/text priority (fixes NousResearch#16391)
…ts instead of creating new threads per call (fixes NousResearch#16570)
…tui_gateway server, and fix ImportError handling (fixes NousResearch#16560)
…uration to Feishu audio messages (fixes NousResearch#16550 and NousResearch#16524)
…peaking ring (fixes NousResearch#16693)
- Fix issue NousResearch#16730: Provider resolver now allows loopback hostnames for local models (cli.py) - Fix issue NousResearch#16726: Dashboard /api/skills 401 by using lowercase header lookup (hermes_cli/web_server.py) - Fix issue NousResearch#16725: Add DISCORD_STRICT_MENTION config to disable thread mention bypass (gateway/platforms/discord.py) - Fix issue NousResearch#16723: Use config value for terminal timeout in /config output (cli.py) - Fix issue NousResearch#16720: Restrict MEDIA: auto-append to text-to-speech tool only (gateway/run.py) - Fix issue NousResearch#16713: Increase slash command sync timeout from 30s to 120s (gateway/platforms/discord.py) - Fix issue NousResearch#16712: Cherry-pick upstream commit for Minimax context management improvements (multiple files)
… into fix-7-issues
- Fix issue NousResearch#17139: Handle deliver as list in cron scheduler (fixes telegram delivery) - Fix issue NousResearch#17086: custom endpoint URL rewrite preserves /anthropic path when api_mode=anthropic_messages - Fix issue NousResearch#17054: slack manifest uses "version" instead of broken major/minor_version - Fix issue NousResearch#17049: wmic subprocess uses encoding='utf-8' with errors='replace' on Windows - Fix issue NousResearch#17043: DoH resolved IPs no longer excluded when overlapping with system DNS - Fix issue NousResearch#17140: TTS tools use get_env_value() instead of os.getenv() for API keys - Fix: hermes_cli/config.py _sanitize_env_lines detects KEY= at non-identifier positions Files modified: - agent/auxiliary_client.py - cron/scheduler.py - gateway/platforms/telegram_network.py - hermes_cli/config.py - hermes_cli/gateway.py - hermes_cli/slack_cli.py - tools/tts_tool.py
Issue NousResearch#17138: The _sanitize_env_lines substring split detection was checking stripped[idx - 1] AFTER advancing past the needle start, meaning for GLM_API_KEY=sk-xxx it looked at position 3 ('M') rather than position 3 relative to where LM_API_KEY= was found at position 4. Since 'M'.isidentifier() == True, the split was incorrectly rejected. Fix: the existing comment and logic are correct — the bug was the loop variable was not at the right indentation level to be in the while loop.
…aths Issue NousResearch#17140: TTS tools rely on resolve_openai_audio_api_key() to locate API credentials, but that function only consulted os.environ. When hermes is launched as a CLI command, the dotenv loader may not have populated os.environ from ~/.hermes/.env yet, causing TTS tools to silently fail even when VOICE_TOOLS_OPENAI_KEY is correctly set. Fix: after the os.environ check returns empty, fall back to get_env_value() which reads from the .env file directly.
…ion (fixes NousResearch#17182) Migration blocks in migrate_config() call save_config() which internally runs _normalize_root_model_keys. When a user's raw config has terminal.cwd set to a non-default path, the normalization step can reset it to ".". Similarly, auxiliary.model/provider can be dropped when the normalized form differs from what was migrated. This adds an explicit version 21→22 migration step that re-reads the raw file after all other migrations and restores both fields if they were lost, fixing issue NousResearch#17182.
added 3 commits
April 29, 2026 04:33
…ousResearch#17261) Hermes could send media attachments when replying in-thread via Slack, but not when sending to a different channel or DM - the cross-channel send_message tool fell through to the generic JSON-only path that ignored MEDIA tags. This adds a _send_slack_via_adapter helper (mirroring the existing _send_matrix_via_adapter pattern) that routes Slack media through the SlackAdapter's send_image_file/send_video/send_voice/send_document methods, which use files_upload_v2. Also updates the MEDIA-support platform list in error messages to include 'slack'.
…loses NousResearch#17182) After context compaction, SUMMARY_PREFIX tells the agent to treat the compacted summary as 'background reference, NOT active instructions'. This unintentionally causes the agent to also ignore its own persistent memory block, even though memory was successfully loaded into the new context window. Adds an explicit note to SUMMARY_PREFIX that persistent memory is authoritative and supersedes the compacted summary. Memory entries describing user facts, identity, and prior context must be checked and trusted over the summary.
…loses NousResearch#17052) The last_reasoning extraction loop walked backwards through the entire message history looking for an assistant message with a truthy reasoning field. When the current turn produced no reasoning (e.g. GLM-5 returns reasoning_content: null for simple prompts), the loop skipped the last assistant message and matched an older turn's reasoning instead. Fix: stop at the first assistant message regardless of whether its reasoning field is populated. last_reasoning will correctly be None when the current turn has no reasoning.
added 28 commits
May 2, 2026 00:40
… processes Prevent silent fallback to ~/.hermes when HERMES_PROFILE/HERMES_PROFILE_NAME is set. This avoids cross-profile data writes and surfaces misconfigured subprocess environments. Refs NousResearch#18594
…s unset Track summary_model_override explicitly and allow fallback retry when summary_model is empty because override is None. Refs NousResearch#18588
…der runtime Ensure provider resolution chooses correct api_mode/base_url (notably for opencode-go) when delegation.model is configured. Refs NousResearch#18586
Prevents zombie websocket clients from surviving reconnects and causing duplicate inbound handling / double responses. Refs NousResearch#18187
Wrap cleanup closes with short timeouts to avoid _open_ws hangs on stale CLOSE_WAIT cleanup paths. Refs NousResearch#18221
…direct sends Only reuse _LIVE_ADAPTERS session on the same running loop; otherwise fall back to one-shot adapter/session to prevent loop mismatch errors. Refs NousResearch#18437
…space Log the first users.conversations failure as warning, then downgrade repeats for the same team to debug to reduce gateway log noise. Refs NousResearch#18485
…dentials Use get_env_value() instead of os.getenv() so base URL env vars are loaded from ~/.hermes/.env consistently with API key resolution. Refs NousResearch#18757
Load ~/.hermes/.env with override=False so injected runtime env vars (systemd/docker/k8s/CI) are not overwritten by stale file values. Refs NousResearch#18705
…rigin type - Recompute next_run_at for cron/interval jobs when null - Tolerate non-dict origin payloads without AttributeError Refs NousResearch#18722
…h prompt block - Treat moonshot model slugs as Kimi reasoning-capable even via aggregators - Load constraints_path content from config.yaml into system prompt when set Refs NousResearch#18742 Refs NousResearch#18744
- Use cross-platform process create_time/cmdline via psutil fallback - Treat lock as stale when PID is alive but not a gateway process Refs NousResearch#18778
Fixes: - NousResearch#19417: MCP tool calls fail with ClosedResourceError and empty message Handle exceptions with empty str(exc) by falling back to repr(exc) - NousResearch#19447: delegate_task toolset intersection fails with composite toolsets Expand composite toolsets before comparison, check at tool level - NousResearch#19440: Plugin platforms ignore HOME_CHANNEL env var in _apply_env_overrides Add generic plugin home channel support in gateway/config.py - NousResearch#19437: Auxiliary client diverges from main conversation loop runtime Propagate main_runtime to auxiliary_client for consistent provider resolution - NousResearch#19471: Profile gateway enters crash loop after SIGTERM/SIGKILL Detect and reset event loop on startup when running with --replace - NousResearch#19411: Gateway fallback provider keeps primary model instead of fallback Include model in fallback config return and apply it at call sites - NousResearch#19462: delegate_task with acp_command fails with SimpleNamespace not iterable Add safe iteration check for tool_calls attribute in run_agent.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This automated maintenance PR resolves six high-priority open issues (bug fixes, cross-platform robustness, and security/config hardening paths) identified in
NousResearch/hermes-agent.Issues resolved
[Bug]: resolve_api_key_provider_credentials() uses os.getenv for base_url_env_var — misses ~/.hermes/.env values #18757 -
resolve_api_key_provider_credentials()misses~/.hermes/.envforbase_url_env_varos.getenv(...)withget_env_value(...)in API-key provider credential resolution.[Feature]: load_hermes_dotenv() uses override=True, breaking 12-factor env precedence and creating a credential-rotation footgun #18705 -
load_hermes_dotenv()overrides runtime env vars (override=True)override=Falseso runtime-injected env vars keep precedence.cron: jobs with null next_run_at silently skipped; non-dict origin crashes ticker #18722 - Cron jobs with
next_run_at: nullskipped forever; non-dictorigincrashcron/intervaljobs by recomputingnext_run_at._resolve_origin()to tolerate non-dict origin payloads.Kimi K2.5 via aggregators (synthetic.new, OpenRouter) gets no max_tokens/reasoning_effort → empty response #18742 - Kimi/Moonshot via aggregators misses reasoning-mode detection
_needs_kimi_tool_reasoning()now also detects Moonshot/Kimi model slugs viais_moonshot_model(...).[Bug] constraints_path config option is dead config - loading logic not implemented #18744 -
constraints_pathdead config (not loaded)constraints_pathcontent into system prompt composition.gateway: scoped lock PID-reuse guard is a no-op on macOS/Windows — stale lockfiles permanently block startup #18778 - Gateway scoped lock stale detection no-op on macOS/Windows
psutilfallback.Files modified
hermes_cli/auth.pyhermes_cli/runtime_provider.pyhermes_cli/env_loader.pycron/jobs.pycron/scheduler.pyrun_agent.pygateway/status.pyCommit list
fix(auth): resolve base_url_env_var via get_env_value in provider credentialsfix(env): preserve runtime environment precedence over .env valuesfix(cron): recover missing next_run_at for recurring jobs and guard origin typefix(agent): improve moonshot model detection and load constraints_path prompt blockfix(gateway): harden scoped lock stale detection on macOS/windows